@@ -26,7 +26,7 @@ use syntax::parse::token::InternedString;
26
26
use syntax:: codemap:: { Span , DUMMY_SP } ;
27
27
use syntax:: ast;
28
28
use 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 } ;
30
30
use syntax:: attr:: { self , Stability , Deprecation , AttrMetaMethods } ;
31
31
use util:: nodemap:: { DefIdMap , FnvHashSet , FnvHashMap } ;
32
32
@@ -37,6 +37,7 @@ use hir::pat_util::EnumerateAndAdjustIterator;
37
37
38
38
use std:: mem:: replace;
39
39
use std:: cmp:: Ordering ;
40
+ use std:: ops:: Deref ;
40
41
41
42
#[ derive( RustcEncodable , RustcDecodable , PartialEq , PartialOrd , Clone , Copy , Debug , Eq , Hash ) ]
42
43
pub enum StabilityLevel {
@@ -322,7 +323,7 @@ impl<'a, 'tcx> Index<'tcx> {
322
323
/// features and possibly prints errors. Returns a list of all
323
324
/// features used.
324
325
pub fn check_unstable_api_usage < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > )
325
- -> FnvHashMap < InternedString , StabilityLevel > {
326
+ -> FnvHashMap < InternedString , attr :: StabilityLevel > {
326
327
let _task = tcx. dep_graph . in_task ( DepNode :: StabilityCheck ) ;
327
328
let ref active_lib_features = tcx. sess . features . borrow ( ) . declared_lib_features ;
328
329
@@ -343,7 +344,7 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
343
344
struct Checker < ' a , ' tcx : ' a > {
344
345
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
345
346
active_features : FnvHashSet < InternedString > ,
346
- used_features : FnvHashMap < InternedString , StabilityLevel > ,
347
+ used_features : FnvHashMap < InternedString , attr :: StabilityLevel > ,
347
348
// Within a block where feature gate checking can be skipped.
348
349
in_skip_block : u32 ,
349
350
}
@@ -367,7 +368,8 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
367
368
368
369
match * stab {
369
370
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 } ) ;
371
373
372
374
if !self . active_features . contains ( feature) {
373
375
let msg = match * reason {
@@ -380,7 +382,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
380
382
}
381
383
}
382
384
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 ( ) ) ;
384
386
385
387
// Stable APIs are always ok to call and deprecated APIs are
386
388
// handled by a lint.
@@ -716,28 +718,32 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
716
718
/// libraries, identify activated features that don't exist and error about them.
717
719
pub fn check_unused_or_stable_features ( sess : & Session ,
718
720
lib_features_used : & FnvHashMap < InternedString ,
719
- StabilityLevel > ) {
721
+ attr :: StabilityLevel > ) {
720
722
let ref declared_lib_features = sess. features . borrow ( ) . declared_lib_features ;
721
723
let mut remaining_lib_features: FnvHashMap < InternedString , Span >
722
724
= declared_lib_features. clone ( ) . into_iter ( ) . collect ( ) ;
723
725
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
+ }
725
729
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" ) ;
727
733
sess. add_lint ( lint:: builtin:: STABLE_FEATURES ,
728
734
ast:: CRATE_NODE_ID ,
729
735
span,
730
- stable_msg . to_string ( ) ) ;
736
+ format_stable_since_msg ( version ) ) ;
731
737
}
732
738
733
739
for ( used_lib_feature, level) in lib_features_used {
734
740
match remaining_lib_features. remove ( used_lib_feature) {
735
741
Some ( span) => {
736
- if * level == Stable {
742
+ if let & attr :: StabilityLevel :: Stable { since : ref version } = level {
737
743
sess. add_lint ( lint:: builtin:: STABLE_FEATURES ,
738
744
ast:: CRATE_NODE_ID ,
739
745
span,
740
- stable_msg . to_string ( ) ) ;
746
+ format_stable_since_msg ( version . deref ( ) ) ) ;
741
747
}
742
748
}
743
749
None => ( /* used but undeclared, handled during the previous ast visit */ )
0 commit comments