Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 411f3ca

Browse files
committed
Auto merge of rust-lang#138844 - petrochenkov:cfgtrace2, r=<try>
expand: Leave traces when expanding `cfg` attributes This is the same as rust-lang#138515, but for `cfg(true)` instead of `cfg_attr`. The difference is that `cfg(true)`s already left "traces" after themselves - the `cfg` attributes themselves, with `expanded_inert_attrs` set to true, with full tokens, available to proc macros. This is not a reasonably expected behavior, but it could not be removed without a replacement, because a [major rustdoc feature](rust-lang/rfcs#3631) and a number of clippy lints rely on it. This PR implements a replacement. This needs a crater run, because it changes observable behavior (in an intended way) - proc macros can no longer see expanded `cfg(true)` attributes. (Some minor unnecessary special casing for `sym::cfg_attr` is also removed in this PR.) r? `@nnethercote`
2 parents d93f678 + 750814d commit 411f3ca

File tree

24 files changed

+88
-108
lines changed

24 files changed

+88
-108
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,7 @@ impl<'a> AstValidator<'a> {
334334
.filter(|attr| {
335335
let arr = [
336336
sym::allow,
337-
sym::cfg,
338-
sym::cfg_attr,
337+
sym::cfg_trace,
339338
sym::cfg_attr_trace,
340339
sym::deny,
341340
sym::expect,

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
593593
}
594594

595595
fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> bool {
596-
if attr.has_name(sym::cfg_attr_trace) {
596+
if attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace) {
597597
// It's not a valid identifier, so avoid printing it
598598
// to keep the printed code reasonably parse-able.
599599
return false;

compiler/rustc_expand/src/config.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,19 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
156156
.collect()
157157
}
158158

159+
pub(crate) fn attr_into_trace(mut attr: Attribute, trace_name: Symbol) -> Attribute {
160+
match &mut attr.kind {
161+
AttrKind::Normal(normal) => {
162+
let NormalAttr { item, tokens } = &mut **normal;
163+
item.path.segments[0].ident.name = trace_name;
164+
// This makes the trace attributes unobservable to token-based proc macros.
165+
*tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::default()));
166+
}
167+
AttrKind::DocComment(..) => unreachable!(),
168+
}
169+
attr
170+
}
171+
159172
#[macro_export]
160173
macro_rules! configure {
161174
($this:ident, $node:ident) => {
@@ -280,16 +293,7 @@ impl<'a> StripUnconfigured<'a> {
280293

281294
// A trace attribute left in AST in place of the original `cfg_attr` attribute.
282295
// 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-
}
296+
let trace_attr = attr_into_trace(cfg_attr.clone(), sym::cfg_attr_trace);
293297

294298
let Some((cfg_predicate, expanded_attrs)) =
295299
rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)

compiler/rustc_expand/src/expand.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, sym};
3333
use smallvec::SmallVec;
3434

3535
use crate::base::*;
36-
use crate::config::StripUnconfigured;
36+
use crate::config::{StripUnconfigured, attr_into_trace};
3737
use crate::errors::{
3838
EmptyDelegationMac, GlobDelegationOutsideImpls, GlobDelegationTraitlessQpath, IncompleteParse,
3939
RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
@@ -1941,7 +1941,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
19411941
let attr_name = attr.ident().unwrap().name;
19421942
// `#[cfg]` and `#[cfg_attr]` are special - they are
19431943
// eagerly evaluated.
1944-
if attr_name != sym::cfg && attr_name != sym::cfg_attr {
1944+
if attr_name != sym::cfg_trace && attr_name != sym::cfg_attr_trace {
19451945
self.cx.sess.psess.buffer_lint(
19461946
UNUSED_ATTRIBUTES,
19471947
attr.span,
@@ -1965,11 +1965,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
19651965
) -> (bool, Option<ast::MetaItem>) {
19661966
let (res, meta_item) = self.cfg().cfg_true(&attr);
19671967
if res {
1968-
// FIXME: `cfg(TRUE)` attributes do not currently remove themselves during expansion,
1969-
// and some tools like rustdoc and clippy rely on that. Find a way to remove them
1970-
// while keeping the tools working.
1971-
self.cx.expanded_inert_attrs.mark(&attr);
1972-
node.visit_attrs(|attrs| attrs.insert(pos, attr));
1968+
// A trace attribute left in AST in place of the original `cfg` attribute.
1969+
// It can later be used by lints or other diagnostics.
1970+
let trace_attr = attr_into_trace(attr, sym::cfg_trace);
1971+
node.visit_attrs(|attrs| attrs.insert(pos, trace_attr));
19731972
}
19741973

19751974
(res, meta_item)

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -760,10 +760,14 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
760760
template!(Word, List: r#""...""#), DuplicatesOk,
761761
EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
762762
),
763-
// Trace that is left when a `cfg_attr` attribute is expanded.
764-
// The attribute is not gated, to avoid stability errors, but it cannot be used in stable or
765-
// unstable code directly because `sym::cfg_attr_trace` is not a valid identifier, it can only
766-
// be generated by the compiler.
763+
// Traces that are left when `cfg` and `cfg_attr` attributes are expanded.
764+
// The attributes are not gated, to avoid stability errors, but they cannot be used in stable
765+
// or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they
766+
// can only be generated by the compiler.
767+
ungated!(
768+
cfg_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk,
769+
EncodeCrossCrate::No
770+
),
767771
ungated!(
768772
cfg_attr_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk,
769773
EncodeCrossCrate::No

compiler/rustc_parse/src/validate_attr.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ use rustc_span::{Span, Symbol, sym};
1616
use crate::{errors, parse_in};
1717

1818
pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
19-
if attr.is_doc_comment() || attr.has_name(sym::cfg_attr_trace) {
19+
if attr.is_doc_comment() || attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace)
20+
{
2021
return;
2122
}
2223

@@ -215,11 +216,7 @@ pub fn check_builtin_meta_item(
215216
template: AttributeTemplate,
216217
deny_unsafety: bool,
217218
) {
218-
// Some special attributes like `cfg` must be checked
219-
// before the generic check, so we skip them here.
220-
let should_skip = |name| name == sym::cfg;
221-
222-
if !should_skip(name) && !is_attr_template_compatible(&template, &meta.kind) {
219+
if !is_attr_template_compatible(&template, &meta.kind) {
223220
emit_malformed_attribute(psess, style, meta.span, name, template);
224221
}
225222

compiler/rustc_passes/src/check_attr.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
272272
| sym::forbid
273273
| sym::cfg
274274
| sym::cfg_attr
275+
| sym::cfg_trace
275276
| sym::cfg_attr_trace
276277
// need to be fixed
277278
| sym::cfi_encoding // FIXME(cfi_encoding)
@@ -574,8 +575,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
574575
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
575576
const ALLOW_LIST: &[rustc_span::Symbol] = &[
576577
// conditional compilation
577-
sym::cfg,
578-
sym::cfg_attr,
578+
sym::cfg_trace,
579579
sym::cfg_attr_trace,
580580
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
581581
sym::test,
@@ -2656,7 +2656,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
26562656
// only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed
26572657
// if we allow more attributes (e.g., tool attributes and `allow/deny/warn`)
26582658
// in where clauses. After that, only `self.check_attributes` should be enough.
2659-
const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr, sym::cfg_attr_trace];
2659+
const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg_trace, sym::cfg_attr_trace];
26602660
let spans = self
26612661
.tcx
26622662
.hir_attrs(where_predicate.hir_id)

compiler/rustc_query_system/src/ich/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod hcx;
88
mod impls_syntax;
99

1010
pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
11-
sym::cfg,
11+
sym::cfg_trace, // FIXME should this really be ignored?
1212
sym::rustc_if_this_changed,
1313
sym::rustc_then_this_would_need,
1414
sym::rustc_dirty,

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ symbols! {
611611
cfg_target_has_atomic_equal_alignment,
612612
cfg_target_thread_local,
613613
cfg_target_vendor,
614+
cfg_trace: "<cfg>", // must not be a valid identifier
614615
cfg_ub_checks,
615616
cfg_version,
616617
cfi,

src/librustdoc/clean/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2773,7 +2773,7 @@ fn add_without_unwanted_attributes<'hir>(
27732773
if ident == sym::doc {
27742774
filter_doc_attr(&mut normal.args, is_inline);
27752775
attrs.push((Cow::Owned(attr), import_parent));
2776-
} else if is_inline || ident != sym::cfg {
2776+
} else if is_inline || ident != sym::cfg_trace {
27772777
// If it's not a `cfg()` attribute, we keep it.
27782778
attrs.push((Cow::Owned(attr), import_parent));
27792779
}

0 commit comments

Comments
 (0)