@@ -8,29 +8,25 @@ use rustc_ast::Attribute;
8
8
use rustc_attr:: VERSION_PLACEHOLDER ;
9
9
use rustc_hir:: intravisit:: Visitor ;
10
10
use 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 } ;
13
13
use rustc_middle:: ty:: TyCtxt ;
14
14
use rustc_span:: symbol:: Symbol ;
15
15
use rustc_span:: { sym, Span } ;
16
16
17
17
use crate :: errors:: { FeaturePreviouslyDeclared , FeatureStableTwice } ;
18
18
19
- fn new_lib_features ( ) -> LibFeatures {
20
- LibFeatures { stable : Default :: default ( ) , unstable : Default :: default ( ) }
21
- }
22
-
23
19
pub struct LibFeatureCollector < ' tcx > {
24
20
tcx : TyCtxt < ' tcx > ,
25
21
lib_features : LibFeatures ,
26
22
}
27
23
28
24
impl < ' tcx > LibFeatureCollector < ' tcx > {
29
25
fn new ( tcx : TyCtxt < ' tcx > ) -> LibFeatureCollector < ' tcx > {
30
- LibFeatureCollector { tcx, lib_features : new_lib_features ( ) }
26
+ LibFeatureCollector { tcx, lib_features : LibFeatures :: default ( ) }
31
27
}
32
28
33
- fn extract ( & self , attr : & Attribute ) -> Option < ( Symbol , Option < Symbol > , Span ) > {
29
+ fn extract ( & self , attr : & Attribute ) -> Option < ( Symbol , FeatureStability , Span ) > {
34
30
let stab_attrs = [
35
31
sym:: stable,
36
32
sym:: unstable,
@@ -72,8 +68,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
72
68
| sym:: rustc_const_unstable
73
69
| sym:: rustc_default_body_unstable
74
70
) ;
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 ) ) ;
77
76
}
78
77
}
79
78
// We need to iterate over the other attributes, because
@@ -86,37 +85,43 @@ impl<'tcx> LibFeatureCollector<'tcx> {
86
85
None
87
86
}
88
87
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 ) {
90
89
let already_in_stable = self . lib_features . stable . contains_key ( & feature) ;
91
90
let already_in_unstable = self . lib_features . unstable . contains_key ( & feature) ;
92
91
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 ;
105
104
}
106
105
107
106
self . lib_features . stable . insert ( feature, ( since, span) ) ;
108
107
}
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 , _) => {
110
117
self . lib_features . unstable . insert ( feature, span) ;
111
118
}
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 , _) => {
115
120
self . tcx . sess . emit_err ( FeaturePreviouslyDeclared {
116
121
span,
117
122
feature,
118
- declared,
119
- prev_declared,
123
+ declared : "unstable" ,
124
+ prev_declared : "stable" ,
120
125
} ) ;
121
126
}
122
127
}
@@ -137,11 +142,11 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {
137
142
}
138
143
}
139
144
140
- fn lib_features ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> LibFeatures {
145
+ fn lib_features ( tcx : TyCtxt < ' _ > , LocalCrate : LocalCrate ) -> LibFeatures {
141
146
// If `staged_api` is not enabled then we aren't allowed to define lib
142
147
// features; there is no point collecting them.
143
148
if !tcx. features ( ) . staged_api {
144
- return new_lib_features ( ) ;
149
+ return LibFeatures :: default ( ) ;
145
150
}
146
151
147
152
let mut collector = LibFeatureCollector :: new ( tcx) ;
0 commit comments