@@ -8,29 +8,25 @@ use rustc_ast::Attribute;
88use rustc_attr:: 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,
@@ -72,8 +68,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
7268 | sym:: rustc_const_unstable
7369 | sym:: rustc_default_body_unstable
7470 ) ;
75- if since. is_some ( ) || is_unstable {
76- return Some ( ( feature, since, attr. span ) ) ;
71+ if is_unstable {
72+ return Some ( ( feature, FeatureStability :: Unstable , attr. span ) ) ;
73+ }
74+ if let Some ( since) = since {
75+ return Some ( ( feature, FeatureStability :: AcceptedSince ( since) , attr. span ) ) ;
7776 }
7877 }
7978 // We need to iterate over the other attributes, because
@@ -86,37 +85,43 @@ impl<'tcx> LibFeatureCollector<'tcx> {
8685 None
8786 }
8887
89- fn collect_feature ( & mut self , feature : Symbol , since : Option < Symbol > , span : Span ) {
88+ fn collect_feature ( & mut self , feature : Symbol , stability : FeatureStability , span : Span ) {
9089 let already_in_stable = self . lib_features . stable . contains_key ( & feature) ;
9190 let already_in_unstable = self . lib_features . unstable . contains_key ( & feature) ;
9291
93- match ( since , already_in_stable, already_in_unstable) {
94- ( Some ( since) , _, false ) => {
95- if let Some ( ( prev_since, _) ) = self . lib_features . stable . get ( & feature) {
96- if * prev_since != since {
97- self . tcx . sess . emit_err ( FeatureStableTwice {
98- span ,
99- feature ,
100- since ,
101- prev_since : * prev_since ,
102- } ) ;
103- return ;
104- }
92+ match ( stability , already_in_stable, already_in_unstable) {
93+ ( FeatureStability :: AcceptedSince ( since) , _, false ) => {
94+ if let Some ( ( prev_since, _) ) = self . lib_features . stable . get ( & feature)
95+ && * prev_since != since
96+ {
97+ self . tcx . sess . emit_err ( FeatureStableTwice {
98+ span ,
99+ feature ,
100+ since ,
101+ prev_since : * prev_since ,
102+ } ) ;
103+ return ;
105104 }
106105
107106 self . lib_features . stable . insert ( feature, ( since, span) ) ;
108107 }
109- ( None , false , _) => {
108+ ( FeatureStability :: AcceptedSince ( _) , _, true ) => {
109+ self . tcx . sess . emit_err ( FeaturePreviouslyDeclared {
110+ span,
111+ feature,
112+ declared : "stable" ,
113+ prev_declared : "unstable" ,
114+ } ) ;
115+ }
116+ ( FeatureStability :: Unstable , false , _) => {
110117 self . lib_features . unstable . insert ( feature, span) ;
111118 }
112- ( Some ( _) , _, true ) | ( None , true , _) => {
113- let declared = if since. is_some ( ) { "stable" } else { "unstable" } ;
114- let prev_declared = if since. is_none ( ) { "stable" } else { "unstable" } ;
119+ ( FeatureStability :: Unstable , true , _) => {
115120 self . tcx . sess . emit_err ( FeaturePreviouslyDeclared {
116121 span,
117122 feature,
118- declared,
119- prev_declared,
123+ declared : "unstable" ,
124+ prev_declared : "stable" ,
120125 } ) ;
121126 }
122127 }
@@ -137,11 +142,11 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {
137142 }
138143}
139144
140- fn lib_features ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> LibFeatures {
145+ fn lib_features ( tcx : TyCtxt < ' _ > , LocalCrate : LocalCrate ) -> LibFeatures {
141146 // If `staged_api` is not enabled then we aren't allowed to define lib
142147 // features; there is no point collecting them.
143148 if !tcx. features ( ) . staged_api {
144- return new_lib_features ( ) ;
149+ return LibFeatures :: default ( ) ;
145150 }
146151
147152 let mut collector = LibFeatureCollector :: new ( tcx) ;
0 commit comments