@@ -26,7 +26,7 @@ use syntax::parse::token::InternedString;
2626use syntax:: codemap:: { Span , DUMMY_SP } ;
2727use syntax:: ast;
2828use syntax:: ast:: { NodeId , Attribute } ;
29- use syntax:: feature_gate:: { GateIssue , emit_feature_err} ;
29+ use syntax:: feature_gate:: { GateIssue , emit_feature_err, find_lang_feature_accepted_version } ;
3030use syntax:: attr:: { self , Stability , Deprecation , AttrMetaMethods } ;
3131use util:: nodemap:: { DefIdMap , FnvHashSet , FnvHashMap } ;
3232
@@ -37,6 +37,7 @@ use hir::pat_util::EnumerateAndAdjustIterator;
3737
3838use std:: mem:: replace;
3939use std:: cmp:: Ordering ;
40+ use std:: ops:: Deref ;
4041
4142#[ derive( RustcEncodable , RustcDecodable , PartialEq , PartialOrd , Clone , Copy , Debug , Eq , Hash ) ]
4243pub enum StabilityLevel {
@@ -322,7 +323,7 @@ impl<'a, 'tcx> Index<'tcx> {
322323/// features and possibly prints errors. Returns a list of all
323324/// features used.
324325pub fn check_unstable_api_usage < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > )
325- -> FnvHashMap < InternedString , StabilityLevel > {
326+ -> FnvHashMap < InternedString , attr :: StabilityLevel > {
326327 let _task = tcx. dep_graph . in_task ( DepNode :: StabilityCheck ) ;
327328 let ref active_lib_features = tcx. sess . features . borrow ( ) . declared_lib_features ;
328329
@@ -343,7 +344,7 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
343344struct Checker < ' a , ' tcx : ' a > {
344345 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
345346 active_features : FnvHashSet < InternedString > ,
346- used_features : FnvHashMap < InternedString , StabilityLevel > ,
347+ used_features : FnvHashMap < InternedString , attr :: StabilityLevel > ,
347348 // Within a block where feature gate checking can be skipped.
348349 in_skip_block : u32 ,
349350}
@@ -367,7 +368,8 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
367368
368369 match * stab {
369370 Some ( & Stability { level : attr:: Unstable { ref reason, issue} , ref feature, .. } ) => {
370- self . used_features . insert ( feature. clone ( ) , Unstable ) ;
371+ self . used_features . insert ( feature. clone ( ) ,
372+ attr:: Unstable { reason : reason. clone ( ) , issue : issue } ) ;
371373
372374 if !self . active_features . contains ( feature) {
373375 let msg = match * reason {
@@ -380,7 +382,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
380382 }
381383 }
382384 Some ( & Stability { ref level, ref feature, .. } ) => {
383- self . used_features . insert ( feature. clone ( ) , StabilityLevel :: from_attr_level ( level) ) ;
385+ self . used_features . insert ( feature. clone ( ) , level. clone ( ) ) ;
384386
385387 // Stable APIs are always ok to call and deprecated APIs are
386388 // handled by a lint.
@@ -716,28 +718,32 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
716718/// libraries, identify activated features that don't exist and error about them.
717719pub fn check_unused_or_stable_features ( sess : & Session ,
718720 lib_features_used : & FnvHashMap < InternedString ,
719- StabilityLevel > ) {
721+ attr :: StabilityLevel > ) {
720722 let ref declared_lib_features = sess. features . borrow ( ) . declared_lib_features ;
721723 let mut remaining_lib_features: FnvHashMap < InternedString , Span >
722724 = declared_lib_features. clone ( ) . into_iter ( ) . collect ( ) ;
723725
724- let stable_msg = "this feature is stable. attribute no longer needed" ;
726+ fn format_stable_since_msg ( version : & str ) -> String {
727+ format ! ( "this feature has been stable since {}. Attribute no longer needed" , version)
728+ }
725729
726- for & span in & sess. features . borrow ( ) . declared_stable_lang_features {
730+ for & ( ref stable_lang_feature, span) in & sess. features . borrow ( ) . declared_stable_lang_features {
731+ let version = find_lang_feature_accepted_version ( stable_lang_feature. deref ( ) )
732+ . expect ( "unexpectedly couldn't find version feature was stabilized" ) ;
727733 sess. add_lint ( lint:: builtin:: STABLE_FEATURES ,
728734 ast:: CRATE_NODE_ID ,
729735 span,
730- stable_msg . to_string ( ) ) ;
736+ format_stable_since_msg ( version ) ) ;
731737 }
732738
733739 for ( used_lib_feature, level) in lib_features_used {
734740 match remaining_lib_features. remove ( used_lib_feature) {
735741 Some ( span) => {
736- if * level == Stable {
742+ if let & attr :: StabilityLevel :: Stable { since : ref version } = level {
737743 sess. add_lint ( lint:: builtin:: STABLE_FEATURES ,
738744 ast:: CRATE_NODE_ID ,
739745 span,
740- stable_msg . to_string ( ) ) ;
746+ format_stable_since_msg ( version . deref ( ) ) ) ;
741747 }
742748 }
743749 None => ( /* used but undeclared, handled during the previous ast visit */ )
0 commit comments