@@ -8,29 +8,25 @@ use rustc_ast::Attribute;
88use rustc_attr:: { rust_version_symbol, VERSION_PLACEHOLDER } ;
99use rustc_hir:: intravisit:: Visitor ;
1010use rustc_middle:: hir:: nested_filter;
11- use rustc_middle:: middle:: lib_features:: LibFeatures ;
12- use rustc_middle:: query:: Providers ;
11+ use rustc_middle:: middle:: lib_features:: { FeatureStability , LibFeatures } ;
12+ use rustc_middle:: query:: { LocalCrate , Providers } ;
1313use rustc_middle:: ty:: TyCtxt ;
1414use rustc_span:: symbol:: Symbol ;
1515use rustc_span:: { sym, Span } ;
1616
1717use crate :: errors:: { FeaturePreviouslyDeclared , FeatureStableTwice } ;
1818
19- fn new_lib_features ( ) -> LibFeatures {
20- LibFeatures { stable : Default :: default ( ) , unstable : Default :: default ( ) }
21- }
22-
2319pub struct LibFeatureCollector < ' tcx > {
2420 tcx : TyCtxt < ' tcx > ,
2521 lib_features : LibFeatures ,
2622}
2723
2824impl < ' tcx > LibFeatureCollector < ' tcx > {
2925 fn new ( tcx : TyCtxt < ' tcx > ) -> LibFeatureCollector < ' tcx > {
30- LibFeatureCollector { tcx, lib_features : new_lib_features ( ) }
26+ LibFeatureCollector { tcx, lib_features : LibFeatures :: default ( ) }
3127 }
3228
33- fn extract ( & self , attr : & Attribute ) -> Option < ( Symbol , Option < Symbol > , Span ) > {
29+ fn extract ( & self , attr : & Attribute ) -> Option < ( Symbol , FeatureStability , Span ) > {
3430 let stab_attrs = [
3531 sym:: stable,
3632 sym:: unstable,
@@ -70,8 +66,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
7066 | sym:: rustc_const_unstable
7167 | sym:: rustc_default_body_unstable
7268 ) ;
73- if since. is_some ( ) || is_unstable {
74- return Some ( ( feature, since, attr. span ) ) ;
69+ if is_unstable {
70+ return Some ( ( feature, FeatureStability :: Unstable , attr. span ) ) ;
71+ }
72+ if let Some ( since) = since {
73+ return Some ( ( feature, FeatureStability :: AcceptedSince ( since) , attr. span ) ) ;
7574 }
7675 }
7776 // We need to iterate over the other attributes, because
@@ -84,37 +83,43 @@ impl<'tcx> LibFeatureCollector<'tcx> {
8483 None
8584 }
8685
87- fn collect_feature ( & mut self , feature : Symbol , since : Option < Symbol > , span : Span ) {
86+ fn collect_feature ( & mut self , feature : Symbol , stability : FeatureStability , span : Span ) {
8887 let already_in_stable = self . lib_features . stable . contains_key ( & feature) ;
8988 let already_in_unstable = self . lib_features . unstable . contains_key ( & feature) ;
9089
91- match ( since , already_in_stable, already_in_unstable) {
92- ( Some ( since) , _, false ) => {
93- if let Some ( ( prev_since, _) ) = self . lib_features . stable . get ( & feature) {
94- if * prev_since != since {
95- self . tcx . sess . emit_err ( FeatureStableTwice {
96- span ,
97- feature ,
98- since ,
99- prev_since : * prev_since ,
100- } ) ;
101- return ;
102- }
90+ match ( stability , already_in_stable, already_in_unstable) {
91+ ( FeatureStability :: AcceptedSince ( since) , _, false ) => {
92+ if let Some ( ( prev_since, _) ) = self . lib_features . stable . get ( & feature)
93+ && * prev_since != since
94+ {
95+ self . tcx . sess . emit_err ( FeatureStableTwice {
96+ span ,
97+ feature ,
98+ since ,
99+ prev_since : * prev_since ,
100+ } ) ;
101+ return ;
103102 }
104103
105104 self . lib_features . stable . insert ( feature, ( since, span) ) ;
106105 }
107- ( None , false , _) => {
106+ ( FeatureStability :: AcceptedSince ( _) , _, true ) => {
107+ self . tcx . sess . emit_err ( FeaturePreviouslyDeclared {
108+ span,
109+ feature,
110+ declared : "stable" ,
111+ prev_declared : "unstable" ,
112+ } ) ;
113+ }
114+ ( FeatureStability :: Unstable , false , _) => {
108115 self . lib_features . unstable . insert ( feature, span) ;
109116 }
110- ( Some ( _) , _, true ) | ( None , true , _) => {
111- let declared = if since. is_some ( ) { "stable" } else { "unstable" } ;
112- let prev_declared = if since. is_none ( ) { "stable" } else { "unstable" } ;
117+ ( FeatureStability :: Unstable , true , _) => {
113118 self . tcx . sess . emit_err ( FeaturePreviouslyDeclared {
114119 span,
115120 feature,
116- declared,
117- prev_declared,
121+ declared : "unstable" ,
122+ prev_declared : "stable" ,
118123 } ) ;
119124 }
120125 }
@@ -135,11 +140,11 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {
135140 }
136141}
137142
138- fn lib_features ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> LibFeatures {
143+ fn lib_features ( tcx : TyCtxt < ' _ > , LocalCrate : LocalCrate ) -> LibFeatures {
139144 // If `staged_api` is not enabled then we aren't allowed to define lib
140145 // features; there is no point collecting them.
141146 if !tcx. features ( ) . staged_api {
142- return new_lib_features ( ) ;
147+ return LibFeatures :: default ( ) ;
143148 }
144149
145150 let mut collector = LibFeatureCollector :: new ( tcx) ;
0 commit comments