From 6d05e2a9afb558e4e9668e54db6747e4d8a8383a Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Sat, 15 Jan 2022 04:16:13 -0500 Subject: [PATCH] add more info to invalid use of #[test] on invalid items --- compiler/rustc_builtin_macros/src/test.rs | 22 ++- src/test/ui/issues/issue-14772.rs | 6 - src/test/ui/issues/issue-14772.stderr | 8 - src/test/ui/test-attrs/test-on-macro.rs | 13 -- src/test/ui/test-attrs/test-on-macro.stderr | 8 - src/test/ui/test-attrs/test-on-not-fn.rs | 80 ++++++++ src/test/ui/test-attrs/test-on-not-fn.stderr | 185 +++++++++++++++++++ 7 files changed, 281 insertions(+), 41 deletions(-) delete mode 100644 src/test/ui/issues/issue-14772.rs delete mode 100644 src/test/ui/issues/issue-14772.stderr delete mode 100644 src/test/ui/test-attrs/test-on-macro.rs delete mode 100644 src/test/ui/test-attrs/test-on-macro.stderr create mode 100644 src/test/ui/test-attrs/test-on-not-fn.rs create mode 100644 src/test/ui/test-attrs/test-on-not-fn.stderr diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index c08b141b557..97cb7aa0dde 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -6,6 +6,7 @@ use rustc_ast::attr; use rustc_ast::ptr::P; use rustc_ast_pretty::pprust; +use rustc_errors::Applicability; use rustc_expand::base::*; use rustc_session::Session; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -102,11 +103,20 @@ pub fn expand_test_or_bench( } }; - if let ast::ItemKind::MacCall(_) = item.kind { - cx.sess.parse_sess.span_diagnostic.span_warn( - item.span, - "`#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead.", - ); + // Note: non-associated fn items are already handled by `expand_test_or_bench` + if !matches!(item.kind, ast::ItemKind::Fn(_)) { + cx.sess + .parse_sess + .span_diagnostic + .struct_span_err( + attr_sp, + "the `#[test]` attribute may only be used on a non-associated function", + ) + .note("the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions") + .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr())) + .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", String::from("#[cfg(test)]"), Applicability::MaybeIncorrect) + .emit(); + return vec![Annotatable::Item(item)]; } @@ -475,7 +485,7 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { (false, _) => true, } } else { - sd.span_err(i.span, "only functions may be used as tests"); + // should be unreachable because `is_test_fn_item` should catch all non-fn items false } } diff --git a/src/test/ui/issues/issue-14772.rs b/src/test/ui/issues/issue-14772.rs deleted file mode 100644 index 8f6745246fd..00000000000 --- a/src/test/ui/issues/issue-14772.rs +++ /dev/null @@ -1,6 +0,0 @@ -// compile-flags: --test - -#[test] -mod foo {} //~ ERROR only functions may be used as tests - -fn main() {} diff --git a/src/test/ui/issues/issue-14772.stderr b/src/test/ui/issues/issue-14772.stderr deleted file mode 100644 index 253fec5e578..00000000000 --- a/src/test/ui/issues/issue-14772.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: only functions may be used as tests - --> $DIR/issue-14772.rs:4:1 - | -LL | mod foo {} - | ^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/test-attrs/test-on-macro.rs b/src/test/ui/test-attrs/test-on-macro.rs deleted file mode 100644 index 0667364d13c..00000000000 --- a/src/test/ui/test-attrs/test-on-macro.rs +++ /dev/null @@ -1,13 +0,0 @@ -// check-pass -// compile-flags:--test - -#![deny(warnings)] - -macro_rules! foo { - () => (fn foo(){}) -} - -#[test] -foo!(); //~ WARNING `#[test]` attribute should not be used on macros - -fn main(){} diff --git a/src/test/ui/test-attrs/test-on-macro.stderr b/src/test/ui/test-attrs/test-on-macro.stderr deleted file mode 100644 index 98190b060ce..00000000000 --- a/src/test/ui/test-attrs/test-on-macro.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: `#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead. - --> $DIR/test-on-macro.rs:11:1 - | -LL | foo!(); - | ^^^^^^^ - -warning: 1 warning emitted - diff --git a/src/test/ui/test-attrs/test-on-not-fn.rs b/src/test/ui/test-attrs/test-on-not-fn.rs new file mode 100644 index 00000000000..b2f681c01d1 --- /dev/null +++ b/src/test/ui/test-attrs/test-on-not-fn.rs @@ -0,0 +1,80 @@ +// compile-flags: --test + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +mod test {} + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +mod loooooooooooooong_teeeeeeeeeest { + /* + this is a comment + this comment goes on for a very long time + this is to pad out the span for this module for a long time + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in + voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat + non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + */ +} + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +extern "C" {} + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +trait Foo {} + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +impl Foo for i32 {} + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +const FOO: i32 = -1_i32; + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +static BAR: u64 = 10_000_u64; + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +enum MyUnit { + Unit, +} + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +struct NewI32(i32); + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +union Spooky { + x: i32, + y: u32, +} + +#[repr(C, align(64))] +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +#[derive(Copy, Clone, Debug)] +struct MoreAttrs { + a: i32, + b: u64, +} + +macro_rules! foo { + () => {}; +} + +#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function +foo!(); + +// make sure it doesn't erroneously trigger on a real test +#[test] +fn real_test() { + assert_eq!(42_i32, 42_i32); +} + +// make sure it works with cfg test +#[cfg(test)] +mod real_tests { + #[cfg(test)] + fn foo() {} + + #[test] + fn bar() { + foo(); + } +} diff --git a/src/test/ui/test-attrs/test-on-not-fn.stderr b/src/test/ui/test-attrs/test-on-not-fn.stderr new file mode 100644 index 00000000000..dd693cf316d --- /dev/null +++ b/src/test/ui/test-attrs/test-on-not-fn.stderr @@ -0,0 +1,185 @@ +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:3:1 + | +LL | #[test] + | ^^^^^^^ +LL | mod test {} + | ----------- expected a non-associated function, found a module + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:6:1 + | +LL | #[test] + | ^^^^^^^ +LL | / mod loooooooooooooong_teeeeeeeeeest { +LL | | /* +LL | | this is a comment +LL | | this comment goes on for a very long time +... | +LL | | */ +LL | | } + | |_- expected a non-associated function, found a module + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:20:1 + | +LL | #[test] + | ^^^^^^^ +LL | extern "C" {} + | ------------- expected a non-associated function, found an extern block + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:23:1 + | +LL | #[test] + | ^^^^^^^ +LL | trait Foo {} + | ------------ expected a non-associated function, found a trait + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:26:1 + | +LL | #[test] + | ^^^^^^^ +LL | impl Foo for i32 {} + | ------------------- expected a non-associated function, found an implementation + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:29:1 + | +LL | #[test] + | ^^^^^^^ +LL | const FOO: i32 = -1_i32; + | ------------------------ expected a non-associated function, found a constant item + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:32:1 + | +LL | #[test] + | ^^^^^^^ +LL | static BAR: u64 = 10_000_u64; + | ----------------------------- expected a non-associated function, found a static item + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:35:1 + | +LL | #[test] + | ^^^^^^^ +LL | / enum MyUnit { +LL | | Unit, +LL | | } + | |_- expected a non-associated function, found an enum + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:40:1 + | +LL | #[test] + | ^^^^^^^ +LL | struct NewI32(i32); + | ------------------- expected a non-associated function, found a struct + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:43:1 + | +LL | #[test] + | ^^^^^^^ +LL | / union Spooky { +LL | | x: i32, +LL | | y: u32, +LL | | } + | |_- expected a non-associated function, found a union + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:50:1 + | +LL | #[test] + | ^^^^^^^ +LL | #[derive(Copy, Clone, Debug)] +LL | / struct MoreAttrs { +LL | | a: i32, +LL | | b: u64, +LL | | } + | |_- expected a non-associated function, found a struct + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-on-not-fn.rs:61:1 + | +LL | #[test] + | ^^^^^^^ +LL | foo!(); + | ------- expected a non-associated function, found an item macro invocation + | + = note: the `#[test]` macro causes a a function to be run on 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 | #[cfg(test)] + | ~~~~~~~~~~~~ + +error: aborting due to 12 previous errors +