@@ -7,8 +7,8 @@ use rustc_ast::tokenstream::{
77 AttrTokenStream , AttrTokenTree , LazyAttrTokenStream , Spacing , TokenTree ,
88} ;
99use 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 ,
1212} ;
1313use rustc_attr_parsing as attr;
1414use rustc_attr_parsing:: validate_attr:: deny_builtin_meta_unsafety;
@@ -21,16 +21,16 @@ use rustc_feature::{
2121 ACCEPTED_LANG_FEATURES , AttributeSafety , EnabledLangFeature , EnabledLibFeature , Features ,
2222 REMOVED_LANG_FEATURES , UNSTABLE_LANG_FEATURES ,
2323} ;
24+ use rustc_hir:: attrs:: AttributeKind ;
25+ use rustc_hir:: { self as hir} ;
2426use rustc_session:: Session ;
2527use 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} ;
2829use tracing:: instrument;
2930
3031use crate :: errors:: {
3132 CrateNameInCfgAttr , CrateTypeInCfgAttr , FeatureNotAllowed , FeatureRemoved ,
32- FeatureRemovedReason , InvalidCfg , MalformedFeatureAttribute , MalformedFeatureAttributeHelp ,
33- RemoveExprNotSupported ,
33+ FeatureRemovedReason , InvalidCfg , RemoveExprNotSupported ,
3434} ;
3535
3636/// A folder that strips out items that do not belong in the current configuration.
@@ -45,44 +45,23 @@ pub struct StripUnconfigured<'a> {
4545}
4646
4747pub 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-
5848 let mut features = Features :: default ( ) ;
5949
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 feature_ident in feature_idents {
8461 // 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) =
63+ REMOVED_LANG_FEATURES . iter ( ) . find ( |f| feature_ident. name == f. feature . name )
64+ {
8665 let pull_note = if let Some ( pull) = f. pull {
8766 format ! (
8867 "; see <https://github.com/rust-lang/rust/pull/{}> for more information" ,
@@ -92,7 +71,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
9271 "" . to_owned ( )
9372 } ;
9473 sess. dcx ( ) . emit_err ( FeatureRemoved {
95- span : mi . span ( ) ,
74+ span : feature_ident . span ,
9675 reason : f. reason . map ( |reason| FeatureRemovedReason { reason } ) ,
9776 removed_rustc_version : f. feature . since ,
9877 pull_note,
@@ -101,10 +80,10 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
10180 }
10281
10382 // If the enabled feature is stable, record it.
104- if let Some ( f) = ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| name == f. name ) {
83+ if let Some ( f) = ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| feature_ident . name == f. name ) {
10584 features. set_enabled_lang_feature ( EnabledLangFeature {
106- gate_name : name,
107- attr_sp : mi . span ( ) ,
85+ gate_name : feature_ident . name ,
86+ attr_sp : feature_ident . span ,
10887 stable_since : Some ( Symbol :: intern ( f. since ) ) ,
10988 } ) ;
11089 continue ;
@@ -114,38 +93,46 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
11493 // unstable and not also listed as one of the allowed features,
11594 // issue an error.
11695 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 } ) ;
96+ if allowed. iter ( ) . all ( |f| feature_ident. name . as_str ( ) != f) {
97+ sess. dcx ( ) . emit_err ( FeatureNotAllowed {
98+ span : feature_ident. span ,
99+ name : feature_ident. name ,
100+ } ) ;
119101 continue ;
120102 }
121103 }
122104
123105 // If the enabled feature is unstable, record it.
124- if UNSTABLE_LANG_FEATURES . iter ( ) . find ( |f| name == f. name ) . is_some ( ) {
106+ if UNSTABLE_LANG_FEATURES . iter ( ) . find ( |f| feature_ident . name == f. name ) . is_some ( ) {
125107 // When the ICE comes a standard library crate, there's a chance that the person
126108 // hitting the ICE may be using -Zbuild-std or similar with an untested target.
127109 // The bug is probably in the standard library and not the compiler in that case,
128110 // but that doesn't really matter - we want a bug report.
129- if features. internal ( name) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
111+ if features. internal ( feature_ident. name )
112+ && !STDLIB_STABLE_CRATES . contains ( & crate_name)
113+ {
130114 sess. using_internal_features . store ( true , std:: sync:: atomic:: Ordering :: Relaxed ) ;
131115 }
132116
133117 features. set_enabled_lang_feature ( EnabledLangFeature {
134- gate_name : name,
135- attr_sp : mi . span ( ) ,
118+ gate_name : feature_ident . name ,
119+ attr_sp : feature_ident . span ,
136120 stable_since : None ,
137121 } ) ;
138122 continue ;
139123 }
140124
141125 // Otherwise, the feature is unknown. Enable it as a lib feature.
142126 // 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 ( ) } ) ;
127+ features. set_enabled_lib_feature ( EnabledLibFeature {
128+ gate_name : feature_ident. name ,
129+ attr_sp : feature_ident. span ,
130+ } ) ;
145131
146132 // Similar to above, detect internal lib features to suppress
147133 // the ICE message that asks for a report.
148- if features. internal ( name) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
134+ if features. internal ( feature_ident. name ) && !STDLIB_STABLE_CRATES . contains ( & crate_name)
135+ {
149136 sess. using_internal_features . store ( true , std:: sync:: atomic:: Ordering :: Relaxed ) ;
150137 }
151138 }
0 commit comments