only discard items with #[test] on it when target is valid

This commit is contained in:
Jana Dönszelmann 2025-10-18 12:10:21 +02:00
parent 1864bf6a51
commit 9dd3caeebe
No known key found for this signature in database
11 changed files with 431 additions and 233 deletions

View file

@ -34,10 +34,6 @@ pub(crate) fn expand_test_case(
check_builtin_macro_attribute(ecx, meta_item, sym::test_case);
warn_on_duplicate_attribute(ecx, &anno_item, sym::test_case);
if !ecx.ecfg.should_test {
return vec![];
}
let sp = ecx.with_def_site_ctxt(attr_sp);
let (mut item, is_stmt) = match anno_item {
Annotatable::Item(item) => (item, false),
@ -54,6 +50,10 @@ pub(crate) fn expand_test_case(
}
};
if !ecx.ecfg.should_test {
return vec![];
}
// `#[test_case]` is valid on functions, consts, and statics. Only modify
// the item in those cases.
match &mut item.kind {
@ -113,11 +113,6 @@ pub(crate) fn expand_test_or_bench(
item: Annotatable,
is_bench: bool,
) -> Vec<Annotatable> {
// If we're not in test configuration, remove the annotated item
if !cx.ecfg.should_test {
return vec![];
}
let (item, is_stmt) = match item {
Annotatable::Item(i) => (i, false),
Annotatable::Stmt(box ast::Stmt { kind: ast::StmtKind::Item(i), .. }) => (i, true),
@ -136,6 +131,11 @@ pub(crate) fn expand_test_or_bench(
};
};
// If we're not in test configuration, remove the annotated item
if !cx.ecfg.should_test {
return vec![];
}
if let Some(attr) = attr::find_by_name(&item.attrs, sym::naked) {
cx.dcx().emit_err(errors::NakedFunctionTestingAttribute {
testing_span: attr_sp,
@ -407,7 +407,7 @@ pub(crate) fn expand_test_or_bench(
fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) {
let dcx = cx.dcx();
let msg = "the `#[test]` attribute may only be used on a non-associated function";
let msg = "the `#[test]` attribute may only be used on a free function";
let level = match item.map(|i| &i.kind) {
// These were a warning before #92959 and need to continue being that to avoid breaking
// stable user code (#94508).

View file

@ -0,0 +1,48 @@
#![feature(test)]
// test is a built-in macro, not a built-in attribute, but it kind of acts like both.
// check its target checking anyway here
#[test]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
mod test {
mod inner { #![test] }
//~^ ERROR inner macro attributes are unstable
//~| ERROR the `#[test]` attribute may only be used on a non-associated function
#[test]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
struct S;
#[test]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
type T = S;
#[test]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
impl S { }
}
// At time of unit test authorship, if compiling without `--test` then
// non-crate-level #[bench] attributes seem to be ignored.
#[bench]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
mod bench {
mod inner { #![bench] }
//~^ ERROR inner macro attributes are unstable
//~| ERROR the `#[test]` attribute may only be used on a non-associated function
#[bench]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
struct S;
#[bench]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
type T = S;
#[bench]
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
impl S { }
}
fn main() {}

View file

@ -0,0 +1,181 @@
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:5:1
|
LL | #[test]
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | / mod test {
LL | | mod inner { #![test] }
... |
LL | | impl S { }
LL | | }
| |_- expected a non-associated function, found a module
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[test]
LL + #[cfg(test)]
|
error[E0658]: inner macro attributes are unstable
--> $DIR/gating-of-test-attrs.rs:8:20
|
LL | mod inner { #![test] }
| ^^^^
|
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:8:17
|
LL | mod inner { #![test] }
| ------------^^^^^^^^--
| | |
| | the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
| expected a non-associated function, found a module
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - mod inner { #![test] }
LL + mod inner { #[cfg(test)] }
|
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:12:5
|
LL | #[test]
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | struct S;
| --------- expected a non-associated function, found a struct
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[test]
LL + #[cfg(test)]
|
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:16:5
|
LL | #[test]
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | type T = S;
| ----------- expected a non-associated function, found a type alias
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[test]
LL + #[cfg(test)]
|
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:20:5
|
LL | #[test]
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | impl S { }
| ---------- expected a non-associated function, found an implementation
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[test]
LL + #[cfg(test)]
|
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:28:1
|
LL | #[bench]
| ^^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | / mod bench {
LL | | mod inner { #![bench] }
... |
LL | | impl S { }
LL | | }
| |_- expected a non-associated function, found a module
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[bench]
LL + #[cfg(test)]
|
error[E0658]: inner macro attributes are unstable
--> $DIR/gating-of-test-attrs.rs:31:20
|
LL | mod inner { #![bench] }
| ^^^^^
|
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:31:17
|
LL | mod inner { #![bench] }
| ------------^^^^^^^^^--
| | |
| | the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
| expected a non-associated function, found a module
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - mod inner { #![bench] }
LL + mod inner { #[cfg(test)] }
|
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:35:5
|
LL | #[bench]
| ^^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | struct S;
| --------- expected a non-associated function, found a struct
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[bench]
LL + #[cfg(test)]
|
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:39:5
|
LL | #[bench]
| ^^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | type T = S;
| ----------- expected a non-associated function, found a type alias
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[bench]
LL + #[cfg(test)]
|
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:43:5
|
LL | #[bench]
| ^^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
LL |
LL | impl S { }
| ---------- expected a non-associated function, found an implementation
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #[bench]
LL + #[cfg(test)]
|
error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -250,38 +250,6 @@ mod macro_export {
//~| HELP remove the attribute
}
// At time of unit test authorship, if compiling without `--test` then
// non-crate-level #[test] attributes seem to be ignored.
#[test]
mod test { mod inner { #![test] }
fn f() { }
struct S;
type T = S;
impl S { }
}
// At time of unit test authorship, if compiling without `--test` then
// non-crate-level #[bench] attributes seem to be ignored.
#[bench]
mod bench {
mod inner { #![bench] }
#[bench]
struct S;
#[bench]
type T = S;
#[bench]
impl S { }
}
#[path = "3800"]
mod path {
mod inner { #![path="3800"] }

View file

@ -1,11 +0,0 @@
// AST-based macro attributes expanding to an empty expression produce an error and not ICE.
#![feature(custom_test_frameworks)]
#![feature(stmt_expr_attributes)]
#![feature(test)]
fn main() {
let _ = #[test] 0; //~ ERROR removing an expression is not supported in this position
let _ = #[bench] 1; //~ ERROR removing an expression is not supported in this position
let _ = #[test_case] 2; //~ ERROR removing an expression is not supported in this position
}

View file

@ -1,20 +0,0 @@
error: removing an expression is not supported in this position
--> $DIR/attr-empty-expr.rs:8:13
|
LL | let _ = #[test] 0;
| ^^^^^^^
error: removing an expression is not supported in this position
--> $DIR/attr-empty-expr.rs:9:13
|
LL | let _ = #[bench] 1;
| ^^^^^^^^
error: removing an expression is not supported in this position
--> $DIR/attr-empty-expr.rs:10:13
|
LL | let _ = #[test_case] 2;
| ^^^^^^^^^^^^
error: aborting due to 3 previous errors

View file

@ -5,8 +5,8 @@ macro_rules! cbor_map {
}
fn main() {
cbor_map! { #[test(test)] 4};
//~^ ERROR removing an expression is not supported in this position
cbor_map! { #[test(test)] 4i32};
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
//~| ERROR attribute must be of the form `#[test]`
//~| WARNING this was previously accepted by the compiler but is being phased out
}

View file

@ -1,13 +1,19 @@
error: removing an expression is not supported in this position
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/issue-111749.rs:8:17
|
LL | cbor_map! { #[test(test)] 4};
| ^^^^^^^^^^^^^
LL | cbor_map! { #[test(test)] 4i32};
| ^^^^^^^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - cbor_map! { #[test(test)] 4i32};
LL + cbor_map! { #[cfg(test)] 4i32};
|
error: attribute must be of the form `#[test]`
--> $DIR/issue-111749.rs:8:17
|
LL | cbor_map! { #[test(test)] 4};
LL | cbor_map! { #[test(test)] 4i32};
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
@ -20,7 +26,7 @@ Future incompatibility report: Future breakage diagnostic:
error: attribute must be of the form `#[test]`
--> $DIR/issue-111749.rs:8:17
|
LL | cbor_map! { #[test(test)] 4};
LL | cbor_map! { #[test(test)] 4i32};
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!

View file

@ -2,7 +2,8 @@
// though only when specified with a full path. `#![test]` is not enough.
// Fixes #114920
#![core::prelude::v1::test]
//~^ ERROR inner macro attributes are unstable
//~| ERROR the `#[test]` attribute may only be used on a non-associated function
fn main() {} // not important to reproduce the issue

View file

@ -0,0 +1,25 @@
error[E0658]: inner macro attributes are unstable
--> $DIR/test-on-crate-root.rs:3:4
|
LL | #![core::prelude::v1::test]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: the `#[test]` attribute may only be used on a non-associated function
--> $DIR/test-on-crate-root.rs:3:1
|
LL | #![core::prelude::v1::test]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
|
help: replace with conditional compilation to make the item only exist when tests are being run
|
LL - #![core::prelude::v1::test]
LL + #[cfg(test)]
|
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.