@@ -7,8 +7,8 @@ use rustc_ast::tokenstream::{
77 AttrTokenStream , AttrTokenTree , LazyAttrTokenStream , Spacing , TokenTree ,
88} ;
99use rustc_ast:: {
10- self as ast, AttrItemKind , AttrKind , AttrStyle , Attribute , EarlyParsedAttribute , HasAttrs ,
11- HasTokens , MetaItem , MetaItemInner , NodeId , NormalAttr ,
10+ self as ast, AttrItemKind , AttrKind , AttrStyle , Attribute , DUMMY_NODE_ID , EarlyParsedAttribute ,
11+ HasAttrs , HasTokens , MetaItem , MetaItemInner , NodeId , NormalAttr ,
1212} ;
1313use rustc_attr_parsing as attr;
1414use rustc_attr_parsing:: {
@@ -20,18 +20,19 @@ use rustc_feature::{
2020 ACCEPTED_LANG_FEATURES , EnabledLangFeature , EnabledLibFeature , Features , REMOVED_LANG_FEATURES ,
2121 UNSTABLE_LANG_FEATURES ,
2222} ;
23- use rustc_hir:: Target ;
23+ use rustc_hir:: attrs:: AttributeKind ;
24+ use rustc_hir:: {
25+ Target , { self as hir} ,
26+ } ;
2427use rustc_parse:: parser:: Recovery ;
2528use rustc_session:: Session ;
2629use rustc_session:: parse:: feature_err;
27- use rustc_span:: { STDLIB_STABLE_CRATES , Span , Symbol , sym} ;
28- use thin_vec:: ThinVec ;
30+ use rustc_span:: { DUMMY_SP , STDLIB_STABLE_CRATES , Span , Symbol , sym} ;
2931use tracing:: instrument;
3032
3133use crate :: errors:: {
3234 CrateNameInCfgAttr , CrateTypeInCfgAttr , FeatureNotAllowed , FeatureRemoved ,
33- FeatureRemovedReason , InvalidCfg , MalformedFeatureAttribute , MalformedFeatureAttributeHelp ,
34- RemoveExprNotSupported ,
35+ FeatureRemovedReason , InvalidCfg , RemoveExprNotSupported ,
3536} ;
3637
3738/// A folder that strips out items that do not belong in the current configuration.
@@ -46,44 +47,23 @@ pub struct StripUnconfigured<'a> {
4647}
4748
4849pub fn features ( sess : & Session , krate_attrs : & [ Attribute ] , crate_name : Symbol ) -> Features {
49- fn feature_list ( attr : & Attribute ) -> ThinVec < ast:: MetaItemInner > {
50- if attr. has_name ( sym:: feature)
51- && let Some ( list) = attr. meta_item_list ( )
52- {
53- list
54- } else {
55- ThinVec :: new ( )
56- }
57- }
58-
5950 let mut features = Features :: default ( ) ;
6051
61- // Process all features enabled in the code.
62- for attr in krate_attrs {
63- for mi in feature_list ( attr) {
64- let name = match mi. ident ( ) {
65- Some ( ident) if mi. is_word ( ) => ident. name ,
66- Some ( ident) => {
67- sess. dcx ( ) . emit_err ( MalformedFeatureAttribute {
68- span : mi. span ( ) ,
69- help : MalformedFeatureAttributeHelp :: Suggestion {
70- span : mi. span ( ) ,
71- suggestion : ident. name ,
72- } ,
73- } ) ;
74- continue ;
75- }
76- None => {
77- sess. dcx ( ) . emit_err ( MalformedFeatureAttribute {
78- span : mi. span ( ) ,
79- help : MalformedFeatureAttributeHelp :: Label { span : mi. span ( ) } ,
80- } ) ;
81- continue ;
82- }
83- } ;
84-
52+ if let Some ( hir:: Attribute :: Parsed ( AttributeKind :: Feature ( feature_idents, _) ) ) =
53+ AttributeParser :: parse_limited (
54+ sess,
55+ krate_attrs,
56+ sym:: feature,
57+ DUMMY_SP ,
58+ DUMMY_NODE_ID ,
59+ Some ( & features) ,
60+ )
61+ {
62+ for feature_ident in feature_idents {
8563 // If the enabled feature has been removed, issue an error.
86- if let Some ( f) = REMOVED_LANG_FEATURES . iter ( ) . find ( |f| name == f. feature . name ) {
64+ if let Some ( f) =
65+ REMOVED_LANG_FEATURES . iter ( ) . find ( |f| feature_ident. name == f. feature . name )
66+ {
8767 let pull_note = if let Some ( pull) = f. pull {
8868 format ! (
8969 "; see <https://github.com/rust-lang/rust/pull/{pull}> for more information" ,
@@ -92,7 +72,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
9272 "" . to_owned ( )
9373 } ;
9474 sess. dcx ( ) . emit_err ( FeatureRemoved {
95- span : mi . span ( ) ,
75+ span : feature_ident . span ,
9676 reason : f. reason . map ( |reason| FeatureRemovedReason { reason } ) ,
9777 removed_rustc_version : f. feature . since ,
9878 pull_note,
@@ -101,10 +81,10 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
10181 }
10282
10383 // If the enabled feature is stable, record it.
104- if let Some ( f) = ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| name == f. name ) {
84+ if let Some ( f) = ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| feature_ident . name == f. name ) {
10585 features. set_enabled_lang_feature ( EnabledLangFeature {
106- gate_name : name,
107- attr_sp : mi . span ( ) ,
86+ gate_name : feature_ident . name ,
87+ attr_sp : feature_ident . span ,
10888 stable_since : Some ( Symbol :: intern ( f. since ) ) ,
10989 } ) ;
11090 continue ;
@@ -114,38 +94,46 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
11494 // unstable and not also listed as one of the allowed features,
11595 // issue an error.
11696 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 } ) ;
97+ if allowed. iter ( ) . all ( |f| feature_ident. name . as_str ( ) != f) {
98+ sess. dcx ( ) . emit_err ( FeatureNotAllowed {
99+ span : feature_ident. span ,
100+ name : feature_ident. name ,
101+ } ) ;
119102 continue ;
120103 }
121104 }
122105
123106 // If the enabled feature is unstable, record it.
124- if UNSTABLE_LANG_FEATURES . iter ( ) . find ( |f| name == f. name ) . is_some ( ) {
107+ if UNSTABLE_LANG_FEATURES . iter ( ) . find ( |f| feature_ident . name == f. name ) . is_some ( ) {
125108 // When the ICE comes from a standard library crate, there's a chance that the person
126109 // hitting the ICE may be using -Zbuild-std or similar with an untested target.
127110 // The bug is probably in the standard library and not the compiler in that case,
128111 // but that doesn't really matter - we want a bug report.
129- if features. internal ( name) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
112+ if features. internal ( feature_ident. name )
113+ && !STDLIB_STABLE_CRATES . contains ( & crate_name)
114+ {
130115 sess. using_internal_features . store ( true , std:: sync:: atomic:: Ordering :: Relaxed ) ;
131116 }
132117
133118 features. set_enabled_lang_feature ( EnabledLangFeature {
134- gate_name : name,
135- attr_sp : mi . span ( ) ,
119+ gate_name : feature_ident . name ,
120+ attr_sp : feature_ident . span ,
136121 stable_since : None ,
137122 } ) ;
138123 continue ;
139124 }
140125
141126 // Otherwise, the feature is unknown. Enable it as a lib feature.
142127 // 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 ( ) } ) ;
128+ features. set_enabled_lib_feature ( EnabledLibFeature {
129+ gate_name : feature_ident. name ,
130+ attr_sp : feature_ident. span ,
131+ } ) ;
145132
146133 // Similar to above, detect internal lib features to suppress
147134 // the ICE message that asks for a report.
148- if features. internal ( name) && !STDLIB_STABLE_CRATES . contains ( & crate_name) {
135+ if features. internal ( feature_ident. name ) && !STDLIB_STABLE_CRATES . contains ( & crate_name)
136+ {
149137 sess. using_internal_features . store ( true , std:: sync:: atomic:: Ordering :: Relaxed ) ;
150138 }
151139 }
0 commit comments