Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions compiler/rustc_builtin_macros/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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 {
Expand Down Expand Up @@ -113,29 +113,29 @@ 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),
other => {
not_testable_error(cx, attr_sp, None);
not_testable_error(cx, is_bench, attr_sp, None);
return vec![other];
}
};

let ast::ItemKind::Fn(fn_) = &item.kind else {
not_testable_error(cx, attr_sp, Some(&item));
not_testable_error(cx, is_bench, attr_sp, Some(&item));
return if is_stmt {
vec![Annotatable::Stmt(Box::new(cx.stmt_item(item.span, item)))]
} else {
vec![Annotatable::Item(item)]
};
};

// 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,
Expand Down Expand Up @@ -405,9 +405,10 @@ pub(crate) fn expand_test_or_bench(
}
}

fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) {
fn not_testable_error(cx: &ExtCtxt<'_>, is_bench: bool, 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 name = if is_bench { "bench" } else { "test" };
let msg = format!("the `#[{name}]` attribute may only be used on a non-associated 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).
Expand All @@ -426,12 +427,16 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
),
);
}
err.with_span_label(attr_sp, "the `#[test]` macro causes a function to be run as a test and has no effect on non-functions")
.with_span_suggestion(attr_sp,
err.span_label(attr_sp, format!("the `#[{name}]` macro causes a function to be run as a test and has no effect on non-functions"));

if !is_bench {
err.with_span_suggestion(attr_sp,
"replace with conditional compilation to make the item only exist when tests are being run",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only give the suggestion of cfg(test) when we're dealing with test attrs

"#[cfg(test)]",
Applicability::MaybeIncorrect)
.emit();
Applicability::MaybeIncorrect).emit();
} else {
err.emit();
}
}

fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, usize, usize) {
Expand Down
2 changes: 0 additions & 2 deletions tests/crashes/114920.rs

This file was deleted.

48 changes: 48 additions & 0 deletions tests/ui/feature-gates/gating-of-test-attrs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#![feature(test)]

// test is a built-in macro, not a built-in attribute, but it kind of acts like both.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New test for test attributes. The previous tests simply asserted no errors would be given but that's not true anymore, and I think they should error!

// 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 `#[bench]` attribute may only be used on a non-associated function
mod bench {
mod inner { #![bench] }
//~^ ERROR inner macro attributes are unstable
//~| ERROR the `#[bench]` attribute may only be used on a non-associated function

#[bench]
//~^ ERROR the `#[bench]` attribute may only be used on a non-associated function
struct S;

#[bench]
//~^ ERROR the `#[bench]` attribute may only be used on a non-associated function
type T = S;

#[bench]
//~^ ERROR the `#[bench]` attribute may only be used on a non-associated function
impl S { }
}

fn main() {}
151 changes: 151 additions & 0 deletions tests/ui/feature-gates/gating-of-test-attrs.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
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 `#[bench]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:28:1
|
LL | #[bench]
| ^^^^^^^^ the `#[bench]` 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

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 `#[bench]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:31:17
|
LL | mod inner { #![bench] }
| ------------^^^^^^^^^--
| | |
| | the `#[bench]` 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

error: the `#[bench]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:35:5
|
LL | #[bench]
| ^^^^^^^^ the `#[bench]` 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

error: the `#[bench]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:39:5
|
LL | #[bench]
| ^^^^^^^^ the `#[bench]` 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

error: the `#[bench]` attribute may only be used on a non-associated function
--> $DIR/gating-of-test-attrs.rs:43:5
|
LL | #[bench]
| ^^^^^^^^ the `#[bench]` 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

error: aborting due to 12 previous errors

For more information about this error, try `rustc --explain E0658`.
32 changes: 0 additions & 32 deletions tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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] }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these were weird here anyway, test isn't a built-in attribute but a built-in macro!


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"] }
Expand Down
Loading
Loading