1111//! A pass that annotates every item and method with its stability level,
1212//! propagating default levels lexically from parent to children ast nodes.
1313
14+ pub use self :: StabilityLevel :: * ;
15+
1416use session:: Session ;
1517use lint;
1618use metadata:: cstore:: LOCAL_CRATE ;
@@ -34,6 +36,18 @@ use rustc_front::visit::{self, FnKind, Visitor};
3436use std:: mem:: replace;
3537use std:: cmp:: Ordering ;
3638
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+
3751/// A stability index, giving the stability level for items and methods.
3852pub struct Index < ' tcx > {
3953 /// This is mostly a cache, except the stabilities of local items
@@ -67,20 +81,19 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
6781 // if parent is deprecated and we're not, inherit this by merging
6882 // deprecated_since and its reason.
6983 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 ( )
7487 }
7588 }
7689
7790 let stab = self . tcx . intern_stability ( stab) ;
7891
7992 // Check if deprecated_since < stable_since. If it is,
8093 // 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} ) => {
8497 // explicit version of iter::order::lt to handle parse errors properly
8598 let mut is_less = false ;
8699 for ( dep_v, stab_v) in dep_since. split ( "." ) . zip ( stab_since. split ( "." ) ) {
@@ -117,7 +130,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
117130 self . index . map . insert ( def_id, Some ( stab) ) ;
118131
119132 // Don't inherit #[stable(feature = "rust1", since = "1.0.0")]
120- if stab. level != attr :: Stable {
133+ if ! stab. level . is_stable ( ) {
121134 let parent = replace ( & mut self . parent , Some ( stab) ) ;
122135 f ( self ) ;
123136 self . parent = parent;
@@ -261,7 +274,7 @@ impl<'tcx> Index<'tcx> {
261274/// features and possibly prints errors. Returns a list of all
262275/// features used.
263276pub fn check_unstable_api_usage ( tcx : & ty:: ctxt )
264- -> FnvHashMap < InternedString , attr :: StabilityLevel > {
277+ -> FnvHashMap < InternedString , StabilityLevel > {
265278 let ref active_lib_features = tcx. sess . features . borrow ( ) . declared_lib_features ;
266279
267280 // Put the active features into a map for quick lookup
@@ -284,7 +297,7 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt)
284297struct Checker < ' a , ' tcx : ' a > {
285298 tcx : & ' a ty:: ctxt < ' tcx > ,
286299 active_features : FnvHashSet < InternedString > ,
287- used_features : FnvHashMap < InternedString , attr :: StabilityLevel > ,
300+ used_features : FnvHashMap < InternedString , StabilityLevel > ,
288301 // Within a block where feature gate checking can be skipped.
289302 in_skip_block : u32 ,
290303}
@@ -303,22 +316,21 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
303316 }
304317
305318 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 ) ;
308321
309322 if !self . active_features . contains ( feature) {
310323 let msg = match * reason {
311324 Some ( ref r) => format ! ( "use of unstable library feature '{}': {}" ,
312325 & feature, & r) ,
313326 None => format ! ( "use of unstable library feature '{}'" , & feature)
314327 } ;
315-
316328 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) ;
318330 }
319331 }
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) ) ;
322334
323335 // Stable APIs are always ok to call and deprecated APIs are
324336 // handled by a lint.
@@ -636,7 +648,7 @@ fn lookup_uncached<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stabil
636648/// libraries, identify activated features that don't exist and error about them.
637649pub fn check_unused_or_stable_features ( sess : & Session ,
638650 lib_features_used : & FnvHashMap < InternedString ,
639- attr :: StabilityLevel > ) {
651+ StabilityLevel > ) {
640652 let ref declared_lib_features = sess. features . borrow ( ) . declared_lib_features ;
641653 let mut remaining_lib_features: FnvHashMap < InternedString , Span >
642654 = declared_lib_features. clone ( ) . into_iter ( ) . collect ( ) ;
@@ -653,7 +665,7 @@ pub fn check_unused_or_stable_features(sess: &Session,
653665 for ( used_lib_feature, level) in lib_features_used {
654666 match remaining_lib_features. remove ( used_lib_feature) {
655667 Some ( span) => {
656- if * level == attr :: Stable {
668+ if * level == Stable {
657669 sess. add_lint ( lint:: builtin:: STABLE_FEATURES ,
658670 ast:: CRATE_NODE_ID ,
659671 span,
0 commit comments