11
11
//! A pass that annotates every item and method with its stability level,
12
12
//! propagating default levels lexically from parent to children ast nodes.
13
13
14
+ pub use self :: StabilityLevel :: * ;
15
+
14
16
use session:: Session ;
15
17
use lint;
16
18
use metadata:: cstore:: LOCAL_CRATE ;
@@ -34,6 +36,18 @@ use rustc_front::visit::{self, FnKind, Visitor};
34
36
use std:: mem:: replace;
35
37
use std:: cmp:: Ordering ;
36
38
39
+ #[ derive( RustcEncodable , RustcDecodable , PartialEq , PartialOrd , Clone , Copy , Debug , Eq , Hash ) ]
40
+ pub enum StabilityLevel {
41
+ Unstable ,
42
+ Stable ,
43
+ }
44
+
45
+ impl StabilityLevel {
46
+ pub fn from_attr_level ( level : & attr:: StabilityLevel ) -> Self {
47
+ if level. is_stable ( ) { Stable } else { Unstable }
48
+ }
49
+ }
50
+
37
51
/// A stability index, giving the stability level for items and methods.
38
52
pub struct Index < ' tcx > {
39
53
/// This is mostly a cache, except the stabilities of local items
@@ -67,20 +81,19 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
67
81
// if parent is deprecated and we're not, inherit this by merging
68
82
// deprecated_since and its reason.
69
83
if let Some ( parent_stab) = self . parent {
70
- if parent_stab. deprecated_since . is_some ( )
71
- && stab. deprecated_since . is_none ( ) {
72
- stab. deprecated_since = parent_stab. deprecated_since . clone ( ) ;
73
- stab. reason = parent_stab. reason . clone ( ) ;
84
+ if parent_stab. depr . is_some ( )
85
+ && stab. depr . is_none ( ) {
86
+ stab. depr = parent_stab. depr . clone ( )
74
87
}
75
88
}
76
89
77
90
let stab = self . tcx . intern_stability ( stab) ;
78
91
79
92
// Check if deprecated_since < stable_since. If it is,
80
93
// this is *almost surely* an accident.
81
- let deprecated_predates_stable = match ( stab. deprecated_since . as_ref ( ) ,
82
- stab . since . as_ref ( ) ) {
83
- ( Some ( dep_since ) , Some ( stab_since) ) => {
94
+ let deprecated_predates_stable = match ( & stab. depr , & stab . level ) {
95
+ ( & Some ( attr :: Deprecation { since : ref dep_since , .. } ) ,
96
+ & attr :: Stable { since : ref stab_since} ) => {
84
97
// explicit version of iter::order::lt to handle parse errors properly
85
98
let mut is_less = false ;
86
99
for ( dep_v, stab_v) in dep_since. split ( "." ) . zip ( stab_since. split ( "." ) ) {
@@ -117,7 +130,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
117
130
self . index . map . insert ( def_id, Some ( stab) ) ;
118
131
119
132
// Don't inherit #[stable(feature = "rust1", since = "1.0.0")]
120
- if stab. level != attr :: Stable {
133
+ if ! stab. level . is_stable ( ) {
121
134
let parent = replace ( & mut self . parent , Some ( stab) ) ;
122
135
f ( self ) ;
123
136
self . parent = parent;
@@ -261,7 +274,7 @@ impl<'tcx> Index<'tcx> {
261
274
/// features and possibly prints errors. Returns a list of all
262
275
/// features used.
263
276
pub fn check_unstable_api_usage ( tcx : & ty:: ctxt )
264
- -> FnvHashMap < InternedString , attr :: StabilityLevel > {
277
+ -> FnvHashMap < InternedString , StabilityLevel > {
265
278
let ref active_lib_features = tcx. sess . features . borrow ( ) . declared_lib_features ;
266
279
267
280
// Put the active features into a map for quick lookup
@@ -284,7 +297,7 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt)
284
297
struct Checker < ' a , ' tcx : ' a > {
285
298
tcx : & ' a ty:: ctxt < ' tcx > ,
286
299
active_features : FnvHashSet < InternedString > ,
287
- used_features : FnvHashMap < InternedString , attr :: StabilityLevel > ,
300
+ used_features : FnvHashMap < InternedString , StabilityLevel > ,
288
301
// Within a block where feature gate checking can be skipped.
289
302
in_skip_block : u32 ,
290
303
}
@@ -303,22 +316,21 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
303
316
}
304
317
305
318
match * stab {
306
- Some ( & Stability { level : attr:: Unstable , ref feature , ref reason, issue, .. } ) => {
307
- self . used_features . insert ( feature. clone ( ) , attr :: Unstable ) ;
319
+ Some ( & Stability { level : attr:: Unstable { ref reason, issue} , ref feature , .. } ) => {
320
+ self . used_features . insert ( feature. clone ( ) , Unstable ) ;
308
321
309
322
if !self . active_features . contains ( feature) {
310
323
let msg = match * reason {
311
324
Some ( ref r) => format ! ( "use of unstable library feature '{}': {}" ,
312
325
& feature, & r) ,
313
326
None => format ! ( "use of unstable library feature '{}'" , & feature)
314
327
} ;
315
-
316
328
emit_feature_err ( & self . tcx . sess . parse_sess . span_diagnostic ,
317
- & feature, span, GateIssue :: Library ( issue) , & msg) ;
329
+ & feature, span, GateIssue :: Library ( Some ( issue) ) , & msg) ;
318
330
}
319
331
}
320
- Some ( & Stability { level, ref feature, .. } ) => {
321
- self . used_features . insert ( feature. clone ( ) , level) ;
332
+ Some ( & Stability { ref level, ref feature, .. } ) => {
333
+ self . used_features . insert ( feature. clone ( ) , StabilityLevel :: from_attr_level ( level) ) ;
322
334
323
335
// Stable APIs are always ok to call and deprecated APIs are
324
336
// handled by a lint.
@@ -636,7 +648,7 @@ fn lookup_uncached<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stabil
636
648
/// libraries, identify activated features that don't exist and error about them.
637
649
pub fn check_unused_or_stable_features ( sess : & Session ,
638
650
lib_features_used : & FnvHashMap < InternedString ,
639
- attr :: StabilityLevel > ) {
651
+ StabilityLevel > ) {
640
652
let ref declared_lib_features = sess. features . borrow ( ) . declared_lib_features ;
641
653
let mut remaining_lib_features: FnvHashMap < InternedString , Span >
642
654
= declared_lib_features. clone ( ) . into_iter ( ) . collect ( ) ;
@@ -653,7 +665,7 @@ pub fn check_unused_or_stable_features(sess: &Session,
653
665
for ( used_lib_feature, level) in lib_features_used {
654
666
match remaining_lib_features. remove ( used_lib_feature) {
655
667
Some ( span) => {
656
- if * level == attr :: Stable {
668
+ if * level == Stable {
657
669
sess. add_lint ( lint:: builtin:: STABLE_FEATURES ,
658
670
ast:: CRATE_NODE_ID ,
659
671
span,
0 commit comments