From 5f2790c3412994b7aaef5ccf350030cd6c4a6ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Mar 2026 10:16:12 +0100 Subject: [PATCH 1/2] using rustc in the middle of an attrpath errors --- tests/ui/attributes/rustc-in-attr-path.rs | 9 +++++++++ tests/ui/attributes/rustc-in-attr-path.stderr | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/attributes/rustc-in-attr-path.rs create mode 100644 tests/ui/attributes/rustc-in-attr-path.stderr diff --git a/tests/ui/attributes/rustc-in-attr-path.rs b/tests/ui/attributes/rustc-in-attr-path.rs new file mode 100644 index 000000000000..302f0239de03 --- /dev/null +++ b/tests/ui/attributes/rustc-in-attr-path.rs @@ -0,0 +1,9 @@ +mod rustc { + pub use std::prelude::v1::test; +} + +#[crate::rustc::test] +//~^ ERROR: attributes starting with `rustc` are reserved for use by the `rustc` compiler +fn foo() {} + +fn main() {} diff --git a/tests/ui/attributes/rustc-in-attr-path.stderr b/tests/ui/attributes/rustc-in-attr-path.stderr new file mode 100644 index 000000000000..62f96a36480b --- /dev/null +++ b/tests/ui/attributes/rustc-in-attr-path.stderr @@ -0,0 +1,8 @@ +error: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/rustc-in-attr-path.rs:5:10 + | +LL | #[crate::rustc::test] + | ^^^^^ + +error: aborting due to 1 previous error + From 3e0572e7b62a118f845b349f9426d0ca61b7ed68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Mar 2026 10:26:23 +0100 Subject: [PATCH 2/2] improve diagnostics for attrs that *contain* the word rustc --- compiler/rustc_resolve/src/errors.rs | 9 +++++++++ compiler/rustc_resolve/src/macros.rs | 14 ++++++++++---- tests/ui/attributes/rustc-in-attr-path.rs | 9 --------- tests/ui/attributes/rustc-in-attr-path.stderr | 8 -------- tests/ui/feature-gates/feature-gate-rustc-attrs.rs | 2 +- .../feature-gates/feature-gate-rustc-attrs.stderr | 2 +- 6 files changed, 21 insertions(+), 23 deletions(-) delete mode 100644 tests/ui/attributes/rustc-in-attr-path.rs delete mode 100644 tests/ui/attributes/rustc-in-attr-path.stderr diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 24c923de6794..4bbb7d8e5571 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1198,6 +1198,15 @@ pub(crate) struct AttributesStartingWithRustcAreReserved { pub(crate) span: Span, } +#[derive(Diagnostic)] +#[diag( + "attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler" +)] +pub(crate) struct AttributesContainingRustcAreReserved { + #[primary_span] + pub(crate) span: Span, +} + #[derive(Diagnostic)] #[diag("cannot use {$article} {$descr} through an import")] pub(crate) struct CannotUseThroughAnImport { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 6ae9d3aaeb23..619e61211984 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -618,14 +618,20 @@ fn smart_resolve_macro_path( } // Report errors for the resolved macro. - for segment in &path.segments { + for (idx, segment) in path.segments.iter().enumerate() { if let Some(args) = &segment.args { self.dcx().emit_err(errors::GenericArgumentsInMacroPath { span: args.span() }); } if kind == MacroKind::Attr && segment.ident.as_str().starts_with("rustc") { - self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved { - span: segment.ident.span, - }); + if idx == 0 { + self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved { + span: segment.ident.span, + }); + } else { + self.dcx().emit_err(errors::AttributesContainingRustcAreReserved { + span: segment.ident.span, + }); + } } } diff --git a/tests/ui/attributes/rustc-in-attr-path.rs b/tests/ui/attributes/rustc-in-attr-path.rs deleted file mode 100644 index 302f0239de03..000000000000 --- a/tests/ui/attributes/rustc-in-attr-path.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod rustc { - pub use std::prelude::v1::test; -} - -#[crate::rustc::test] -//~^ ERROR: attributes starting with `rustc` are reserved for use by the `rustc` compiler -fn foo() {} - -fn main() {} diff --git a/tests/ui/attributes/rustc-in-attr-path.stderr b/tests/ui/attributes/rustc-in-attr-path.stderr deleted file mode 100644 index 62f96a36480b..000000000000 --- a/tests/ui/attributes/rustc-in-attr-path.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: attributes starting with `rustc` are reserved for use by the `rustc` compiler - --> $DIR/rustc-in-attr-path.rs:5:10 - | -LL | #[crate::rustc::test] - | ^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs index e7b2eca6f858..6382af32efb2 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -12,7 +12,7 @@ mod unknown { pub macro rustc() {} } fn f() {} #[unknown::rustc] -//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~^ ERROR attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler //~| ERROR expected attribute, found macro `unknown::rustc` //~| NOTE not an attribute fn g() {} diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr index d58603883f15..bc0db8b81aef 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -10,7 +10,7 @@ error: expected attribute, found macro `rustc::unknown` LL | #[rustc::unknown] | ^^^^^^^^^^^^^^ not an attribute -error: attributes starting with `rustc` are reserved for use by the `rustc` compiler +error: attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/feature-gate-rustc-attrs.rs:14:12 | LL | #[unknown::rustc]