@@ -24,7 +24,6 @@ use rustc_session::Session;
24
24
use rustc_span:: edition:: { Edition , ALL_EDITIONS } ;
25
25
use rustc_span:: symbol:: { sym, Symbol } ;
26
26
use rustc_span:: { Span , DUMMY_SP } ;
27
- use thin_vec:: ThinVec ;
28
27
29
28
/// A folder that strips out items that do not belong in the current configuration.
30
29
pub struct StripUnconfigured < ' a > {
@@ -37,7 +36,7 @@ pub struct StripUnconfigured<'a> {
37
36
pub lint_node_id : NodeId ,
38
37
}
39
38
40
- fn get_features ( sess : & Session , krate_attrs : & [ ast :: Attribute ] ) -> Features {
39
+ pub fn features ( sess : & Session , krate_attrs : & [ Attribute ] ) -> Features {
41
40
fn feature_removed ( sess : & Session , span : Span , reason : Option < & str > ) {
42
41
sess. emit_err ( FeatureRemoved {
43
42
span,
@@ -191,39 +190,16 @@ fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features {
191
190
features
192
191
}
193
192
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 ,
225
199
} ;
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 ( ) }
227
203
}
228
204
229
205
#[ macro_export]
@@ -254,11 +230,6 @@ impl<'a> StripUnconfigured<'a> {
254
230
}
255
231
}
256
232
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
-
262
233
/// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.
263
234
/// This is only used during the invocation of `derive` proc-macros,
264
235
/// which require that we cfg-expand their entire input.
@@ -281,7 +252,7 @@ impl<'a> StripUnconfigured<'a> {
281
252
. iter ( )
282
253
. flat_map ( |tree| match tree. clone ( ) {
283
254
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) ) ;
285
256
286
257
if self . in_cfg ( & data. attrs ) {
287
258
data. tokens = LazyAttrTokenStream :: new (
@@ -319,12 +290,16 @@ impl<'a> StripUnconfigured<'a> {
319
290
/// the syntax of any `cfg_attr` is incorrect.
320
291
fn process_cfg_attrs < T : HasAttrs > ( & self , node : & mut T ) {
321
292
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) ) ;
323
294
} ) ;
324
295
}
325
296
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
+ }
328
303
}
329
304
330
305
/// Parse and expand a single `cfg_attr` attribute into a list of attributes
@@ -334,9 +309,9 @@ impl<'a> StripUnconfigured<'a> {
334
309
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
335
310
/// is in the original source file. Gives a compiler error if the syntax of
336
311
/// 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 > {
338
313
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 {
340
315
return vec ! [ ] ;
341
316
} ;
342
317
@@ -365,10 +340,10 @@ impl<'a> StripUnconfigured<'a> {
365
340
// `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
366
341
expanded_attrs
367
342
. 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) ) )
369
344
. collect ( )
370
345
} 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 ( )
372
347
}
373
348
}
374
349
0 commit comments