diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index ec7cdd3624dc3..236d10d77b92a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -113,3 +113,30 @@ impl NoArgsAttributeParser for RustcVarianceOfOpaquesParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVarianceOfOpaques; } + +pub(crate) struct ReexportTestHarnessMainParser; + +impl SingleAttributeParser for ReexportTestHarnessMainParser { + const PATH: &[Symbol] = &[sym::reexport_test_harness_main]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(nv) = args.name_value() else { + cx.expected_name_value( + args.span().unwrap_or(cx.inner_span), + Some(sym::reexport_test_harness_main), + ); + return None; + }; + + let Some(name) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + + Some(AttributeKind::ReexportTestHarnessMain(name)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index fa9f5b5859262..63795886785b1 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -188,6 +188,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 6138ffc8d9544..1634c726e32a2 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -990,6 +990,9 @@ pub enum AttributeKind { /// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute) RecursionLimit { attr_span: Span, limit_span: Span, limit: Limit }, + /// Represents `#[reexport_test_harness_main]` + ReexportTestHarnessMain(Symbol), + /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 7ec1920152a5e..5162c6feec315 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -87,6 +87,7 @@ impl AttributeKind { ProcMacroDerive { .. } => No, ProfilerRuntime => No, RecursionLimit { .. } => No, + ReexportTestHarnessMain(..) => No, Repr { .. } => No, RustcAllocator => No, RustcAllocatorZeroed => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4784456a59d9c..2dd87391ed9a6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -284,6 +284,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Pointee(..) | AttributeKind::ProfilerRuntime | AttributeKind::RecursionLimit { .. } + | AttributeKind::ReexportTestHarnessMain(..) // handled below this loop and elsewhere | AttributeKind::Repr { .. } | AttributeKind::RustcAllocator @@ -414,8 +415,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::feature | sym::register_tool | sym::rustc_no_implicit_bounds - | sym::test_runner - | sym::reexport_test_harness_main, + | sym::test_runner, .. ] => {} [name, rest@..] => { diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 9695a73c137f6..83debd17777ae 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -467,26 +467,26 @@ mod no_implicit_prelude { #[reexport_test_harness_main = "2900"] //~^ WARN crate-level attribute should be -//~| HELP add a `!` mod reexport_test_harness_main { +//~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![reexport_test_harness_main="2900"] } - //~^ WARN crate-level attribute should be + //~^ WARN the `#![reexport_test_harness_main]` attribute can only be used at the crate root #[reexport_test_harness_main = "2900"] fn f() { } //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[reexport_test_harness_main = "2900"] struct S; //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[reexport_test_harness_main = "2900"] type T = S; //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[reexport_test_harness_main = "2900"] impl S { } //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } // Cannot feed "2700" to `#[macro_escape]` without signaling an error. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index d69daf45b3524..482980dde3bf5 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -186,22 +186,6 @@ warning: unknown lint: `x5100` LL | #[deny(x5100)] impl S { } | ^^^^^ -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:1 - | -LL | #[reexport_test_harness_main = "2900"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 - | -LL | #![warn(unused_attributes, unknown_lints)] - | ^^^^^^^^^^^^^^^^^ -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:1 | @@ -217,6 +201,11 @@ LL | | } | |_- not an `extern` block | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 + | +LL | #![warn(unused_attributes, unknown_lints)] + | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:1 @@ -245,56 +234,6 @@ LL | #![feature(rust1)] | = note: `#[warn(stable_features)]` on by default -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:17 - | -LL | mod inner { #![reexport_test_harness_main="2900"] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5 - | -LL | #[reexport_test_harness_main = "2900"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 - | -LL | #[reexport_test_harness_main = "2900"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 - | -LL | #[reexport_test_harness_main = "2900"] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 - | -LL | #[reexport_test_harness_main = "2900"] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] impl S { } - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:17 | @@ -771,6 +710,76 @@ LL | #[no_implicit_prelude] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_implicit_prelude]` can be applied to crates and modules +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:1 + | +LL | #[reexport_test_harness_main = "2900"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:1 + | +LL | / mod reexport_test_harness_main { +LL | | +LL | | mod inner { #![reexport_test_harness_main="2900"] } +... | +LL | | } + | |_^ + +warning: the `#![reexport_test_harness_main]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:17 + | +LL | mod inner { #![reexport_test_harness_main="2900"] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5 + | +LL | #[reexport_test_harness_main = "2900"] fn f() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:44 + | +LL | #[reexport_test_harness_main = "2900"] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 + | +LL | #[reexport_test_harness_main = "2900"] struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:44 + | +LL | #[reexport_test_harness_main = "2900"] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 + | +LL | #[reexport_test_harness_main = "2900"] type T = S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:44 + | +LL | #[reexport_test_harness_main = "2900"] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 + | +LL | #[reexport_test_harness_main = "2900"] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:44 + | +LL | #[reexport_test_harness_main = "2900"] impl S { } + | ^^^^^^^^^^ + warning: `#[macro_escape]` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:5 |