Skip to content

Commit 013fb92

Browse files
Auto merge of #147841 - jdonszelmann:test-macro-ice, r=<try>
Fix ICE when applying test macro to crate root
2 parents ab1d244 + 3e897fe commit 013fb92

File tree

11 files changed

+414
-234
lines changed

11 files changed

+414
-234
lines changed

compiler/rustc_builtin_macros/src/test.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ pub(crate) fn expand_test_case(
3434
check_builtin_macro_attribute(ecx, meta_item, sym::test_case);
3535
warn_on_duplicate_attribute(ecx, &anno_item, sym::test_case);
3636

37-
if !ecx.ecfg.should_test {
38-
return vec![];
39-
}
40-
4137
let sp = ecx.with_def_site_ctxt(attr_sp);
4238
let (mut item, is_stmt) = match anno_item {
4339
Annotatable::Item(item) => (item, false),
@@ -54,6 +50,10 @@ pub(crate) fn expand_test_case(
5450
}
5551
};
5652

53+
if !ecx.ecfg.should_test {
54+
return vec![];
55+
}
56+
5757
// `#[test_case]` is valid on functions, consts, and statics. Only modify
5858
// the item in those cases.
5959
match &mut item.kind {
@@ -113,29 +113,29 @@ pub(crate) fn expand_test_or_bench(
113113
item: Annotatable,
114114
is_bench: bool,
115115
) -> Vec<Annotatable> {
116-
// If we're not in test configuration, remove the annotated item
117-
if !cx.ecfg.should_test {
118-
return vec![];
119-
}
120-
121116
let (item, is_stmt) = match item {
122117
Annotatable::Item(i) => (i, false),
123118
Annotatable::Stmt(box ast::Stmt { kind: ast::StmtKind::Item(i), .. }) => (i, true),
124119
other => {
125-
not_testable_error(cx, attr_sp, None);
120+
not_testable_error(cx, is_bench, attr_sp, None);
126121
return vec![other];
127122
}
128123
};
129124

130125
let ast::ItemKind::Fn(fn_) = &item.kind else {
131-
not_testable_error(cx, attr_sp, Some(&item));
126+
not_testable_error(cx, is_bench, attr_sp, Some(&item));
132127
return if is_stmt {
133128
vec![Annotatable::Stmt(Box::new(cx.stmt_item(item.span, item)))]
134129
} else {
135130
vec![Annotatable::Item(item)]
136131
};
137132
};
138133

134+
// If we're not in test configuration, remove the annotated item
135+
if !cx.ecfg.should_test {
136+
return vec![];
137+
}
138+
139139
if let Some(attr) = attr::find_by_name(&item.attrs, sym::naked) {
140140
cx.dcx().emit_err(errors::NakedFunctionTestingAttribute {
141141
testing_span: attr_sp,
@@ -405,9 +405,10 @@ pub(crate) fn expand_test_or_bench(
405405
}
406406
}
407407

408-
fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) {
408+
fn not_testable_error(cx: &ExtCtxt<'_>, is_bench: bool, attr_sp: Span, item: Option<&ast::Item>) {
409409
let dcx = cx.dcx();
410-
let msg = "the `#[test]` attribute may only be used on a non-associated function";
410+
let name = if is_bench { "bench" } else { "test" };
411+
let msg = format!("the `#[{name}]` attribute may only be used on a non-associated function",);
411412
let level = match item.map(|i| &i.kind) {
412413
// These were a warning before #92959 and need to continue being that to avoid breaking
413414
// stable user code (#94508).
@@ -426,12 +427,16 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
426427
),
427428
);
428429
}
429-
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")
430-
.with_span_suggestion(attr_sp,
430+
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"));
431+
432+
if !is_bench {
433+
err.with_span_suggestion(attr_sp,
431434
"replace with conditional compilation to make the item only exist when tests are being run",
432435
"#[cfg(test)]",
433-
Applicability::MaybeIncorrect)
434-
.emit();
436+
Applicability::MaybeIncorrect).emit();
437+
} else {
438+
err.emit();
439+
}
435440
}
436441

437442
fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, usize, usize) {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#![feature(test)]
2+
3+
// test is a built-in macro, not a built-in attribute, but it kind of acts like both.
4+
// check its target checking anyway here
5+
#[test]
6+
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
7+
mod test {
8+
mod inner { #![test] }
9+
//~^ ERROR inner macro attributes are unstable
10+
//~| ERROR the `#[test]` attribute may only be used on a non-associated function
11+
12+
#[test]
13+
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
14+
struct S;
15+
16+
#[test]
17+
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
18+
type T = S;
19+
20+
#[test]
21+
//~^ ERROR the `#[test]` attribute may only be used on a non-associated function
22+
impl S { }
23+
}
24+
25+
// At time of unit test authorship, if compiling without `--test` then
26+
// non-crate-level #[bench] attributes seem to be ignored.
27+
28+
#[bench]
29+
//~^ ERROR the `#[bench]` attribute may only be used on a non-associated function
30+
mod bench {
31+
mod inner { #![bench] }
32+
//~^ ERROR inner macro attributes are unstable
33+
//~| ERROR the `#[bench]` attribute may only be used on a non-associated function
34+
35+
#[bench]
36+
//~^ ERROR the `#[bench]` attribute may only be used on a non-associated function
37+
struct S;
38+
39+
#[bench]
40+
//~^ ERROR the `#[bench]` attribute may only be used on a non-associated function
41+
type T = S;
42+
43+
#[bench]
44+
//~^ ERROR the `#[bench]` attribute may only be used on a non-associated function
45+
impl S { }
46+
}
47+
48+
fn main() {}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
error: the `#[test]` attribute may only be used on a non-associated function
2+
--> $DIR/gating-of-test-attrs.rs:5:1
3+
|
4+
LL | #[test]
5+
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
6+
LL |
7+
LL | / mod test {
8+
LL | | mod inner { #![test] }
9+
... |
10+
LL | | impl S { }
11+
LL | | }
12+
| |_- expected a non-associated function, found a module
13+
|
14+
help: replace with conditional compilation to make the item only exist when tests are being run
15+
|
16+
LL - #[test]
17+
LL + #[cfg(test)]
18+
|
19+
20+
error[E0658]: inner macro attributes are unstable
21+
--> $DIR/gating-of-test-attrs.rs:8:20
22+
|
23+
LL | mod inner { #![test] }
24+
| ^^^^
25+
|
26+
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
27+
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
28+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
29+
30+
error: the `#[test]` attribute may only be used on a non-associated function
31+
--> $DIR/gating-of-test-attrs.rs:8:17
32+
|
33+
LL | mod inner { #![test] }
34+
| ------------^^^^^^^^--
35+
| | |
36+
| | the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
37+
| expected a non-associated function, found a module
38+
|
39+
help: replace with conditional compilation to make the item only exist when tests are being run
40+
|
41+
LL - mod inner { #![test] }
42+
LL + mod inner { #[cfg(test)] }
43+
|
44+
45+
error: the `#[test]` attribute may only be used on a non-associated function
46+
--> $DIR/gating-of-test-attrs.rs:12:5
47+
|
48+
LL | #[test]
49+
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
50+
LL |
51+
LL | struct S;
52+
| --------- expected a non-associated function, found a struct
53+
|
54+
help: replace with conditional compilation to make the item only exist when tests are being run
55+
|
56+
LL - #[test]
57+
LL + #[cfg(test)]
58+
|
59+
60+
error: the `#[test]` attribute may only be used on a non-associated function
61+
--> $DIR/gating-of-test-attrs.rs:16:5
62+
|
63+
LL | #[test]
64+
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
65+
LL |
66+
LL | type T = S;
67+
| ----------- expected a non-associated function, found a type alias
68+
|
69+
help: replace with conditional compilation to make the item only exist when tests are being run
70+
|
71+
LL - #[test]
72+
LL + #[cfg(test)]
73+
|
74+
75+
error: the `#[test]` attribute may only be used on a non-associated function
76+
--> $DIR/gating-of-test-attrs.rs:20:5
77+
|
78+
LL | #[test]
79+
| ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions
80+
LL |
81+
LL | impl S { }
82+
| ---------- expected a non-associated function, found an implementation
83+
|
84+
help: replace with conditional compilation to make the item only exist when tests are being run
85+
|
86+
LL - #[test]
87+
LL + #[cfg(test)]
88+
|
89+
90+
error: the `#[bench]` attribute may only be used on a non-associated function
91+
--> $DIR/gating-of-test-attrs.rs:28:1
92+
|
93+
LL | #[bench]
94+
| ^^^^^^^^ the `#[bench]` macro causes a function to be run as a test and has no effect on non-functions
95+
LL |
96+
LL | / mod bench {
97+
LL | | mod inner { #![bench] }
98+
... |
99+
LL | | impl S { }
100+
LL | | }
101+
| |_- expected a non-associated function, found a module
102+
103+
error[E0658]: inner macro attributes are unstable
104+
--> $DIR/gating-of-test-attrs.rs:31:20
105+
|
106+
LL | mod inner { #![bench] }
107+
| ^^^^^
108+
|
109+
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
110+
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
111+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
112+
113+
error: the `#[bench]` attribute may only be used on a non-associated function
114+
--> $DIR/gating-of-test-attrs.rs:31:17
115+
|
116+
LL | mod inner { #![bench] }
117+
| ------------^^^^^^^^^--
118+
| | |
119+
| | the `#[bench]` macro causes a function to be run as a test and has no effect on non-functions
120+
| expected a non-associated function, found a module
121+
122+
error: the `#[bench]` attribute may only be used on a non-associated function
123+
--> $DIR/gating-of-test-attrs.rs:35:5
124+
|
125+
LL | #[bench]
126+
| ^^^^^^^^ the `#[bench]` macro causes a function to be run as a test and has no effect on non-functions
127+
LL |
128+
LL | struct S;
129+
| --------- expected a non-associated function, found a struct
130+
131+
error: the `#[bench]` attribute may only be used on a non-associated function
132+
--> $DIR/gating-of-test-attrs.rs:39:5
133+
|
134+
LL | #[bench]
135+
| ^^^^^^^^ the `#[bench]` macro causes a function to be run as a test and has no effect on non-functions
136+
LL |
137+
LL | type T = S;
138+
| ----------- expected a non-associated function, found a type alias
139+
140+
error: the `#[bench]` attribute may only be used on a non-associated function
141+
--> $DIR/gating-of-test-attrs.rs:43:5
142+
|
143+
LL | #[bench]
144+
| ^^^^^^^^ the `#[bench]` macro causes a function to be run as a test and has no effect on non-functions
145+
LL |
146+
LL | impl S { }
147+
| ---------- expected a non-associated function, found an implementation
148+
149+
error: aborting due to 12 previous errors
150+
151+
For more information about this error, try `rustc --explain E0658`.

tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -250,38 +250,6 @@ mod macro_export {
250250
//~| HELP remove the attribute
251251
}
252252

253-
// At time of unit test authorship, if compiling without `--test` then
254-
// non-crate-level #[test] attributes seem to be ignored.
255-
256-
#[test]
257-
mod test { mod inner { #![test] }
258-
259-
fn f() { }
260-
261-
struct S;
262-
263-
type T = S;
264-
265-
impl S { }
266-
}
267-
268-
// At time of unit test authorship, if compiling without `--test` then
269-
// non-crate-level #[bench] attributes seem to be ignored.
270-
271-
#[bench]
272-
mod bench {
273-
mod inner { #![bench] }
274-
275-
#[bench]
276-
struct S;
277-
278-
#[bench]
279-
type T = S;
280-
281-
#[bench]
282-
impl S { }
283-
}
284-
285253
#[path = "3800"]
286254
mod path {
287255
mod inner { #![path="3800"] }

0 commit comments

Comments
 (0)