Auto merge of #138515 - petrochenkov:cfgtrace, r= · rust-lang/rust@c78b933 (original) (raw)
1
1
`//! Conditional compilation stripping.
`
2
2
``
``
3
`+
use std::iter;
`
``
4
+
3
5
`use rustc_ast::ptr::P;
`
4
6
`use rustc_ast::token::{Delimiter, Token, TokenKind};
`
5
7
`use rustc_ast::tokenstream::{
`
6
8
`AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree,
`
7
9
`};
`
8
10
`use rustc_ast::{
`
9
``
`-
self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner, NodeId,
`
``
11
`+
self as ast, AttrKind, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner,
`
``
12
`+
NodeId, NormalAttr,
`
10
13
`};
`
11
14
`use rustc_attr_parsing as attr;
`
12
15
`use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
`
`@@ -275,10 +278,23 @@ impl<'a> StripUnconfigured<'a> {
`
275
278
`pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec {
`
276
279
` validate_attr::check_attribute_safety(&self.sess.psess, AttributeSafety::Normal, &cfg_attr);
`
277
280
``
``
281
`` +
// A trace attribute left in AST in place of the original cfg_attr
attribute.
``
``
282
`+
// It can later be used by lints or other diagnostics.
`
``
283
`+
let mut trace_attr = cfg_attr.clone();
`
``
284
`+
match &mut trace_attr.kind {
`
``
285
`+
AttrKind::Normal(normal) => {
`
``
286
`+
let NormalAttr { item, tokens } = &mut **normal;
`
``
287
`+
item.path.segments[0].ident.name = sym::cfg_attr_trace;
`
``
288
`+
// This makes the trace attributes unobservable to token-based proc macros.
`
``
289
`+
*tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::default()));
`
``
290
`+
}
`
``
291
`+
AttrKind::DocComment(..) => unreachable!(),
`
``
292
`+
}
`
``
293
+
278
294
`let Some((cfg_predicate, expanded_attrs)) =
`
279
295
` rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)
`
280
296
`else {
`
281
``
`-
return vec![];
`
``
297
`+
return vec![trace_attr];
`
282
298
`};
`
283
299
``
284
300
`// Lint on zero attributes in source.
`
`@@ -292,22 +308,21 @@ impl<'a> StripUnconfigured<'a> {
`
292
308
`}
`
293
309
``
294
310
`if !attr::cfg_matches(&cfg_predicate, &self.sess, self.lint_node_id, self.features) {
`
295
``
`-
return vec![];
`
``
311
`+
return vec![trace_attr];
`
296
312
`}
`
297
313
``
298
314
`if recursive {
`
299
315
`` // We call process_cfg_attr
recursively in case there's a
``
300
316
`` // cfg_attr
inside of another cfg_attr
. E.g.
``
301
317
`` // #[cfg_attr(false, cfg_attr(true, some_attr))]
.
``
302
``
`-
expanded_attrs
`
``
318
`+
let expanded_attrs = expanded_attrs
`
303
319
`.into_iter()
`
304
``
`-
.flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(cfg_attr, item)))
`
305
``
`-
.collect()
`
``
320
`+
.flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(cfg_attr, item)));
`
``
321
`+
iter::once(trace_attr).chain(expanded_attrs).collect()
`
306
322
`} else {
`
307
``
`-
expanded_attrs
`
308
``
`-
.into_iter()
`
309
``
`-
.map(|item| self.expand_cfg_attr_item(cfg_attr, item))
`
310
``
`-
.collect()
`
``
323
`+
let expanded_attrs =
`
``
324
`+
expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(cfg_attr, item));
`
``
325
`+
iter::once(trace_attr).chain(expanded_attrs).collect()
`
311
326
`}
`
312
327
`}
`
313
328
``