expand: Leave traces when expanding cfg attributes

This commit is contained in:
Vadim Petrochenkov 2025-03-22 21:42:34 +03:00
parent 65899c06f1
commit 92d802eda6
24 changed files with 88 additions and 108 deletions

View file

@ -156,6 +156,19 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
.collect()
}
pub(crate) fn attr_into_trace(mut attr: Attribute, trace_name: Symbol) -> Attribute {
match &mut attr.kind {
AttrKind::Normal(normal) => {
let NormalAttr { item, tokens } = &mut **normal;
item.path.segments[0].ident.name = trace_name;
// This makes the trace attributes unobservable to token-based proc macros.
*tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::default()));
}
AttrKind::DocComment(..) => unreachable!(),
}
attr
}
#[macro_export]
macro_rules! configure {
($this:ident, $node:ident) => {
@ -280,16 +293,7 @@ impl<'a> StripUnconfigured<'a> {
// A trace attribute left in AST in place of the original `cfg_attr` attribute.
// It can later be used by lints or other diagnostics.
let mut trace_attr = cfg_attr.clone();
match &mut trace_attr.kind {
AttrKind::Normal(normal) => {
let NormalAttr { item, tokens } = &mut **normal;
item.path.segments[0].ident.name = sym::cfg_attr_trace;
// This makes the trace attributes unobservable to token-based proc macros.
*tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::default()));
}
AttrKind::DocComment(..) => unreachable!(),
}
let trace_attr = attr_into_trace(cfg_attr.clone(), sym::cfg_attr_trace);
let Some((cfg_predicate, expanded_attrs)) =
rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)

View file

@ -33,7 +33,7 @@ use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, sym};
use smallvec::SmallVec;
use crate::base::*;
use crate::config::StripUnconfigured;
use crate::config::{StripUnconfigured, attr_into_trace};
use crate::errors::{
EmptyDelegationMac, GlobDelegationOutsideImpls, GlobDelegationTraitlessQpath, IncompleteParse,
RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
@ -2003,7 +2003,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
let attr_name = attr.ident().unwrap().name;
// `#[cfg]` and `#[cfg_attr]` are special - they are
// eagerly evaluated.
if attr_name != sym::cfg && attr_name != sym::cfg_attr_trace {
if attr_name != sym::cfg_trace && attr_name != sym::cfg_attr_trace {
self.cx.sess.psess.buffer_lint(
UNUSED_ATTRIBUTES,
attr.span,
@ -2027,11 +2027,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
) -> (bool, Option<ast::MetaItem>) {
let (res, meta_item) = self.cfg().cfg_true(&attr);
if res {
// FIXME: `cfg(TRUE)` attributes do not currently remove themselves during expansion,
// and some tools like rustdoc and clippy rely on that. Find a way to remove them
// while keeping the tools working.
self.cx.expanded_inert_attrs.mark(&attr);
node.visit_attrs(|attrs| attrs.insert(pos, attr));
// A trace attribute left in AST in place of the original `cfg` attribute.
// It can later be used by lints or other diagnostics.
let trace_attr = attr_into_trace(attr, sym::cfg_trace);
node.visit_attrs(|attrs| attrs.insert(pos, trace_attr));
}
(res, meta_item)