Rollup merge of #153532 - jdonszelmann:attributes-containing-rustc, r=petrochenkov Attributes containing rustc r? @petrochenkov I noticed that attributes *containing* the word rustc as a segment also error with a message referring to "starting with rustc". The first commit shows this going wrong by re-exporting `#[test]`, a built-in macro, from a module called rustc. The 2nd commit addresses this by changing the diagnostic. However, given the wording I wonder if the real solution shouldn't be to allow attributes containing a `rustc` segment and only disallow them when they start. In other words, actually implement the behavior that the original diagnostic pointed out.
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index c9dad4d..9684d3a 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs
@@ -1199,6 +1199,15 @@ pub(crate) struct AttributesStartingWithRustcAreReserved { } #[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 { #[primary_span]
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 6ae9d3a..619e612 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/feature-gates/feature-gate-rustc-attrs.rs b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs index e7b2eca..6382af3 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 d586038..bc0db8b 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 @@ 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]