@@ -24,7 +24,6 @@ use rustc_session::Session;
2424use rustc_span:: edition:: { Edition , ALL_EDITIONS } ;
2525use rustc_span:: symbol:: { sym, Symbol } ;
2626use rustc_span:: { Span , DUMMY_SP } ;
27- use thin_vec:: ThinVec ;
2827
2928/// A folder that strips out items that do not belong in the current configuration.
3029pub struct StripUnconfigured < ' a > {
@@ -37,7 +36,7 @@ pub struct StripUnconfigured<'a> {
3736 pub lint_node_id : NodeId ,
3837}
3938
40- fn get_features ( sess : & Session , krate_attrs : & [ ast :: Attribute ] ) -> Features {
39+ pub fn features ( sess : & Session , krate_attrs : & [ Attribute ] ) -> Features {
4140 fn feature_removed ( sess : & Session , span : Span , reason : Option < & str > ) {
4241 sess. emit_err ( FeatureRemoved {
4342 span,
@@ -191,39 +190,16 @@ fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features {
191190 features
192191}
193192
194- /// `cfg_attr`-process the crate's attributes and compute the crate's features.
195- pub fn features (
196- sess : & Session ,
197- mut krate : ast:: Crate ,
198- lint_node_id : NodeId ,
199- ) -> ( ast:: Crate , Features ) {
200- let mut strip_unconfigured =
201- StripUnconfigured { sess, features : None , config_tokens : false , lint_node_id } ;
202-
203- let unconfigured_attrs = krate. attrs . clone ( ) ;
204- let diag = & sess. parse_sess . span_diagnostic ;
205- let err_count = diag. err_count ( ) ;
206- let features = match strip_unconfigured. configure_krate_attrs ( krate. attrs ) {
207- None => {
208- // The entire crate is unconfigured.
209- krate. attrs = ast:: AttrVec :: new ( ) ;
210- krate. items = ThinVec :: new ( ) ;
211- Features :: default ( )
212- }
213- Some ( attrs) => {
214- krate. attrs = attrs;
215- let features = get_features ( sess, & krate. attrs ) ;
216- if err_count == diag. err_count ( ) {
217- // Avoid reconfiguring malformed `cfg_attr`s.
218- strip_unconfigured. features = Some ( & features) ;
219- // Run configuration again, this time with features available
220- // so that we can perform feature-gating.
221- strip_unconfigured. configure_krate_attrs ( unconfigured_attrs) ;
222- }
223- features
224- }
193+ pub fn pre_configure_attrs ( sess : & Session , attrs : & [ Attribute ] ) -> ast:: AttrVec {
194+ let strip_unconfigured = StripUnconfigured {
195+ sess,
196+ features : None ,
197+ config_tokens : false ,
198+ lint_node_id : ast:: CRATE_NODE_ID ,
225199 } ;
226- ( krate, features)
200+ let attrs: ast:: AttrVec =
201+ attrs. iter ( ) . flat_map ( |attr| strip_unconfigured. process_cfg_attr ( attr) ) . collect ( ) ;
202+ if strip_unconfigured. in_cfg ( & attrs) { attrs } else { ast:: AttrVec :: new ( ) }
227203}
228204
229205#[ macro_export]
@@ -254,11 +230,6 @@ impl<'a> StripUnconfigured<'a> {
254230 }
255231 }
256232
257- fn configure_krate_attrs ( & self , mut attrs : ast:: AttrVec ) -> Option < ast:: AttrVec > {
258- attrs. flat_map_in_place ( |attr| self . process_cfg_attr ( attr) ) ;
259- self . in_cfg ( & attrs) . then_some ( attrs)
260- }
261-
262233 /// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.
263234 /// This is only used during the invocation of `derive` proc-macros,
264235 /// which require that we cfg-expand their entire input.
@@ -281,7 +252,7 @@ impl<'a> StripUnconfigured<'a> {
281252 . iter ( )
282253 . flat_map ( |tree| match tree. clone ( ) {
283254 AttrTokenTree :: Attributes ( mut data) => {
284- data. attrs . flat_map_in_place ( |attr| self . process_cfg_attr ( attr) ) ;
255+ data. attrs . flat_map_in_place ( |attr| self . process_cfg_attr ( & attr) ) ;
285256
286257 if self . in_cfg ( & data. attrs ) {
287258 data. tokens = LazyAttrTokenStream :: new (
@@ -319,12 +290,16 @@ impl<'a> StripUnconfigured<'a> {
319290 /// the syntax of any `cfg_attr` is incorrect.
320291 fn process_cfg_attrs < T : HasAttrs > ( & self , node : & mut T ) {
321292 node. visit_attrs ( |attrs| {
322- attrs. flat_map_in_place ( |attr| self . process_cfg_attr ( attr) ) ;
293+ attrs. flat_map_in_place ( |attr| self . process_cfg_attr ( & attr) ) ;
323294 } ) ;
324295 }
325296
326- fn process_cfg_attr ( & self , attr : Attribute ) -> Vec < Attribute > {
327- if attr. has_name ( sym:: cfg_attr) { self . expand_cfg_attr ( attr, true ) } else { vec ! [ attr] }
297+ fn process_cfg_attr ( & self , attr : & Attribute ) -> Vec < Attribute > {
298+ if attr. has_name ( sym:: cfg_attr) {
299+ self . expand_cfg_attr ( attr, true )
300+ } else {
301+ vec ! [ attr. clone( ) ]
302+ }
328303 }
329304
330305 /// Parse and expand a single `cfg_attr` attribute into a list of attributes
@@ -334,9 +309,9 @@ impl<'a> StripUnconfigured<'a> {
334309 /// Gives a compiler warning when the `cfg_attr` contains no attributes and
335310 /// is in the original source file. Gives a compiler error if the syntax of
336311 /// the attribute is incorrect.
337- pub ( crate ) fn expand_cfg_attr ( & self , attr : Attribute , recursive : bool ) -> Vec < Attribute > {
312+ pub ( crate ) fn expand_cfg_attr ( & self , attr : & Attribute , recursive : bool ) -> Vec < Attribute > {
338313 let Some ( ( cfg_predicate, expanded_attrs) ) =
339- rustc_parse:: parse_cfg_attr ( & attr, & self . sess . parse_sess ) else {
314+ rustc_parse:: parse_cfg_attr ( attr, & self . sess . parse_sess ) else {
340315 return vec ! [ ] ;
341316 } ;
342317
@@ -365,10 +340,10 @@ impl<'a> StripUnconfigured<'a> {
365340 // `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
366341 expanded_attrs
367342 . into_iter ( )
368- . flat_map ( |item| self . process_cfg_attr ( self . expand_cfg_attr_item ( & attr, item) ) )
343+ . flat_map ( |item| self . process_cfg_attr ( & self . expand_cfg_attr_item ( attr, item) ) )
369344 . collect ( )
370345 } else {
371- expanded_attrs. into_iter ( ) . map ( |item| self . expand_cfg_attr_item ( & attr, item) ) . collect ( )
346+ expanded_attrs. into_iter ( ) . map ( |item| self . expand_cfg_attr_item ( attr, item) ) . collect ( )
372347 }
373348 }
374349
0 commit comments