@@ -7,8 +7,8 @@ use rustc_ast::tokenstream::{
7
7
AttrTokenStream , AttrTokenTree , LazyAttrTokenStream , Spacing , TokenTree ,
8
8
} ;
9
9
use rustc_ast:: {
10
- self as ast, AttrKind , AttrStyle , Attribute , HasAttrs , HasTokens , MetaItem , MetaItemInner ,
11
- NodeId , NormalAttr ,
10
+ self as ast, AttrKind , AttrStyle , Attribute , DUMMY_NODE_ID , HasAttrs , HasTokens , MetaItem ,
11
+ MetaItemInner , NodeId , NormalAttr ,
12
12
} ;
13
13
use rustc_attr_parsing as attr;
14
14
use rustc_attr_parsing:: validate_attr:: deny_builtin_meta_unsafety;
@@ -21,16 +21,16 @@ use rustc_feature::{
21
21
ACCEPTED_LANG_FEATURES , AttributeSafety , EnabledLangFeature , EnabledLibFeature , Features ,
22
22
REMOVED_LANG_FEATURES , UNSTABLE_LANG_FEATURES ,
23
23
} ;
24
+ use rustc_hir:: attrs:: AttributeKind ;
25
+ use rustc_hir:: { self as hir} ;
24
26
use rustc_session:: Session ;
25
27
use rustc_session:: parse:: feature_err;
26
- use rustc_span:: { STDLIB_STABLE_CRATES , Span , Symbol , sym} ;
27
- use thin_vec:: ThinVec ;
28
+ use rustc_span:: { DUMMY_SP , STDLIB_STABLE_CRATES , Span , Symbol , sym} ;
28
29
use tracing:: instrument;
29
30
30
31
use crate :: errors:: {
31
32
CrateNameInCfgAttr , CrateTypeInCfgAttr , FeatureNotAllowed , FeatureRemoved ,
32
- FeatureRemovedReason , InvalidCfg , MalformedFeatureAttribute , MalformedFeatureAttributeHelp ,
33
- RemoveExprNotSupported ,
33
+ FeatureRemovedReason , InvalidCfg , RemoveExprNotSupported ,
34
34
} ;
35
35
36
36
/// A folder that strips out items that do not belong in the current configuration.
@@ -45,44 +45,21 @@ pub struct StripUnconfigured<'a> {
45
45
}
46
46
47
47
pub fn features ( sess : & Session , krate_attrs : & [ Attribute ] , crate_name : Symbol ) -> Features {
48
- fn feature_list ( attr : & Attribute ) -> ThinVec < ast:: MetaItemInner > {
49
- if attr. has_name ( sym:: feature)
50
- && let Some ( list) = attr. meta_item_list ( )
51
- {
52
- list
53
- } else {
54
- ThinVec :: new ( )
55
- }
56
- }
57
-
58
48
let mut features = Features :: default ( ) ;
59
49
60
- // Process all features enabled in the code.
61
- for attr in krate_attrs {
62
- for mi in feature_list ( attr) {
63
- let name = match mi. ident ( ) {
64
- Some ( ident) if mi. is_word ( ) => ident. name ,
65
- Some ( ident) => {
66
- sess. dcx ( ) . emit_err ( MalformedFeatureAttribute {
67
- span : mi. span ( ) ,
68
- help : MalformedFeatureAttributeHelp :: Suggestion {
69
- span : mi. span ( ) ,
70
- suggestion : ident. name ,
71
- } ,
72
- } ) ;
73
- continue ;
74
- }
75
- None => {
76
- sess. dcx ( ) . emit_err ( MalformedFeatureAttribute {
77
- span : mi. span ( ) ,
78
- help : MalformedFeatureAttributeHelp :: Label { span : mi. span ( ) } ,
79
- } ) ;
80
- continue ;
81
- }
82
- } ;
83
-
50
+ if let Some ( hir:: Attribute :: Parsed ( AttributeKind :: Feature ( feature_idents, _) ) ) =
51
+ AttributeParser :: parse_limited (
52
+ sess,
53
+ krate_attrs,
54
+ sym:: feature,
55
+ DUMMY_SP ,
56
+ DUMMY_NODE_ID ,
57
+ Some ( & features) ,
58
+ )
59
+ {
60
+ for name in feature_idents {
84
61
// If the enabled feature has been removed, issue an error.
85
- if let Some ( f) = REMOVED_LANG_FEATURES . iter ( ) . find ( |f| name == f. feature . name ) {
62
+ if let Some ( f) = REMOVED_LANG_FEATURES . iter ( ) . find ( |f| name. name == f. feature . name ) {
86
63
let pull_note = if let Some ( pull) = f. pull {
87
64
format ! (
88
65
"; see <https://github.com/rust-lang/rust/pull/{}> for more information" ,
@@ -92,7 +69,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
92
69
"" . to_owned ( )
93
70
} ;
94
71
sess. dcx ( ) . emit_err ( FeatureRemoved {
95
- span : mi . span ( ) ,
72
+ span : name . span ,
96
73
reason : f. reason . map ( |reason| FeatureRemovedReason { reason } ) ,
97
74
removed_rustc_version : f. feature . since ,
98
75
pull_note,
@@ -101,10 +78,10 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
101
78
}
102
79
103
80
// If the enabled feature is stable, record it.
104
- if let Some ( f) = ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| name == f. name ) {
81
+ if let Some ( f) = ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| name. name == f. name ) {
105
82
features. set_enabled_lang_feature ( EnabledLangFeature {
106
- gate_name : name,
107
- attr_sp : mi . span ( ) ,
83
+ gate_name : name. name ,
84
+ attr_sp : name . span ,
108
85
stable_since : Some ( Symbol :: intern ( f. since ) ) ,
109
86
} ) ;
110
87
continue ;
@@ -114,38 +91,40 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
114
91
// unstable and not also listed as one of the allowed features,
115
92
// issue an error.
116
93
if let Some ( allowed) = sess. opts . unstable_opts . allow_features . as_ref ( ) {
117
- if allowed. iter ( ) . all ( |f| name. as_str ( ) != f) {
118
- sess. dcx ( ) . emit_err ( FeatureNotAllowed { span : mi . span ( ) , name } ) ;
94
+ if allowed. iter ( ) . all ( |f| name. name . as_str ( ) != f) {
95
+ sess. dcx ( ) . emit_err ( FeatureNotAllowed { span : name . span , name : name . name } ) ;
119
96
continue ;
120
97
}
121
98
}
122
99
123
100
// If the enabled feature is unstable, record it.
124
- if UNSTABLE_LANG_FEATURES . iter ( ) . find ( |f| name == f. name ) . is_some ( ) {
101
+ if UNSTABLE_LANG_FEATURES . iter ( ) . find ( |f| name. name == f. name ) . is_some ( ) {
125
102
// When the ICE comes a standard library crate, there's a chance that the person
126
103
// hitting the ICE may be using -Zbuild-std or similar with an untested target.
127
104
// The bug is probably in the standard library and not the compiler in that case,
128
105
// but that doesn't really matter - we want a bug report.
129
- if features. internal ( name) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
106
+ if features. internal ( name. name ) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
130
107
sess. using_internal_features . store ( true , std:: sync:: atomic:: Ordering :: Relaxed ) ;
131
108
}
132
109
133
110
features. set_enabled_lang_feature ( EnabledLangFeature {
134
- gate_name : name,
135
- attr_sp : mi . span ( ) ,
111
+ gate_name : name. name ,
112
+ attr_sp : name . span ,
136
113
stable_since : None ,
137
114
} ) ;
138
115
continue ;
139
116
}
140
117
141
118
// Otherwise, the feature is unknown. Enable it as a lib feature.
142
119
// It will be checked later whether the feature really exists.
143
- features
144
- . set_enabled_lib_feature ( EnabledLibFeature { gate_name : name, attr_sp : mi. span ( ) } ) ;
120
+ features. set_enabled_lib_feature ( EnabledLibFeature {
121
+ gate_name : name. name ,
122
+ attr_sp : name. span ,
123
+ } ) ;
145
124
146
125
// Similar to above, detect internal lib features to suppress
147
126
// the ICE message that asks for a report.
148
- if features. internal ( name) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
127
+ if features. internal ( name. name ) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
149
128
sess. using_internal_features . store ( true , std:: sync:: atomic:: Ordering :: Relaxed ) ;
150
129
}
151
130
}
0 commit comments