@@ -8,29 +8,25 @@ use rustc_ast::Attribute;
8
8
use rustc_attr:: { rust_version_symbol, 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,
@@ -70,8 +66,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
70
66
| sym:: rustc_const_unstable
71
67
| sym:: rustc_default_body_unstable
72
68
) ;
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 ) ) ;
75
74
}
76
75
}
77
76
// We need to iterate over the other attributes, because
@@ -84,37 +83,43 @@ impl<'tcx> LibFeatureCollector<'tcx> {
84
83
None
85
84
}
86
85
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 ) {
88
87
let already_in_stable = self . lib_features . stable . contains_key ( & feature) ;
89
88
let already_in_unstable = self . lib_features . unstable . contains_key ( & feature) ;
90
89
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 ;
103
102
}
104
103
105
104
self . lib_features . stable . insert ( feature, ( since, span) ) ;
106
105
}
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 , _) => {
108
115
self . lib_features . unstable . insert ( feature, span) ;
109
116
}
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 , _) => {
113
118
self . tcx . sess . emit_err ( FeaturePreviouslyDeclared {
114
119
span,
115
120
feature,
116
- declared,
117
- prev_declared,
121
+ declared : "unstable" ,
122
+ prev_declared : "stable" ,
118
123
} ) ;
119
124
}
120
125
}
@@ -135,11 +140,11 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {
135
140
}
136
141
}
137
142
138
- fn lib_features ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> LibFeatures {
143
+ fn lib_features ( tcx : TyCtxt < ' _ > , LocalCrate : LocalCrate ) -> LibFeatures {
139
144
// If `staged_api` is not enabled then we aren't allowed to define lib
140
145
// features; there is no point collecting them.
141
146
if !tcx. features ( ) . staged_api {
142
- return new_lib_features ( ) ;
147
+ return LibFeatures :: default ( ) ;
143
148
}
144
149
145
150
let mut collector = LibFeatureCollector :: new ( tcx) ;
0 commit comments