Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit a9bf9ea

Browse files
committed
Add UI tests for the expect attribute (RFC-2383)
* Add UI tests with macros for the `expect` attribute (RFC-2383) * Addressed review comments - mostly UI test updates (RFC-2383) * Documented lint level attribute on macro not working bug (RFC-2383) See `rust#87391`
1 parent 33a5945 commit a9bf9ea

18 files changed

+424
-4
lines changed

compiler/rustc_lint/src/expect.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@ pub fn check_expectations(tcx: TyCtxt<'_>) {
1616
&tcx.lint_levels(()).lint_expectations;
1717

1818
for (id, expectation) in lint_expectations {
19-
if fulfilled_expectations.contains(id) {
20-
continue;
19+
if !fulfilled_expectations.contains(id) {
20+
emit_unfulfilled_expectation_lint(tcx, expectation);
2121
}
22-
23-
emit_unfulfilled_expectation_lint(tcx, expectation);
2422
}
2523
}
2624

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// check-pass
2+
3+
#![feature(lint_reasons)]
4+
5+
#![warn(unused)]
6+
7+
// This expect attribute should catch all lint triggers
8+
#[expect(unused_variables)]
9+
fn check_multiple_lints_1() {
10+
let value_i = 0xff00ff;
11+
let value_ii = 0xff00ff;
12+
let value_iii = 0xff00ff;
13+
let value_iiii = 0xff00ff;
14+
let value_iiiii = 0xff00ff;
15+
}
16+
17+
// This expect attribute should catch all lint triggers
18+
#[expect(unused_mut)]
19+
fn check_multiple_lints_2() {
20+
let mut a = 0xa;
21+
let mut b = 0xb;
22+
let mut c = 0xc;
23+
println!("The ABC goes as: {:#x} {:#x} {:#x}", a, b, c);
24+
}
25+
26+
// This expect attribute should catch all lint triggers
27+
#[expect(while_true)]
28+
fn check_multiple_lints_3() {
29+
// `while_true` is an early lint
30+
while true {}
31+
32+
while true {}
33+
34+
while true {}
35+
36+
while true {}
37+
38+
while true {}
39+
}
40+
41+
fn main() {
42+
check_multiple_lints_1();
43+
check_multiple_lints_2();
44+
check_multiple_lints_3();
45+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// check-pass
2+
3+
#![feature(lint_reasons)]
4+
5+
#![warn(unused)]
6+
7+
#![expect(unused_mut)]
8+
//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
9+
//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
10+
11+
#![expect(unused_variables)]
12+
13+
fn main() {
14+
let x = 0;
15+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: this lint expectation is unfulfilled
2+
--> $DIR/crate_level_expect.rs:7:1
3+
|
4+
LL | #![expect(unused_mut)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
8+
9+
warning: 1 warning emitted
10+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// check-pass
2+
3+
#![feature(lint_reasons)]
4+
5+
#![warn(unused)]
6+
7+
macro_rules! expect_inside_macro {
8+
() => {
9+
#[expect(unused_variables)]
10+
let x = 0;
11+
};
12+
}
13+
14+
fn main() {
15+
expect_inside_macro!();
16+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// check-pass
2+
3+
#![feature(lint_reasons)]
4+
5+
#![warn(unused_variables)]
6+
7+
macro_rules! trigger_unused_variables_macro {
8+
() => {
9+
let x = 0;
10+
//~^ WARNING unused variable: `x` [unused_variables]
11+
//~| WARNING unused variable: `x` [unused_variables]
12+
};
13+
}
14+
15+
pub fn check_macro() {
16+
// This should trigger the `unused_variables` from inside the macro
17+
trigger_unused_variables_macro!();
18+
}
19+
20+
// This should be fulfilled by the macro
21+
#[expect(unused_variables)]
22+
pub fn check_expect_on_item() {
23+
trigger_unused_variables_macro!();
24+
}
25+
26+
pub fn check_expect_on_macro() {
27+
// This should be fulfilled by the macro
28+
#[expect(unused_variables)]
29+
trigger_unused_variables_macro!();
30+
31+
// FIXME: Lint attributes currently don't work directly on macros, and
32+
// therefore also doesn't work for the new `expect` attribute. This bug
33+
// is being tracked in rust#87391. The test will until then produce two
34+
// warnings about the unused variable x.
35+
//
36+
// The expectation is still marked as fulfilled. I'm not totally why but
37+
// my guess is that this will remain working when rust#87391 has been fixed.
38+
}
39+
40+
fn main() {
41+
42+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
warning: unused variable: `x`
2+
--> $DIR/expect_lint_from_macro.rs:9:13
3+
|
4+
LL | let x = 0;
5+
| ^ help: if this is intentional, prefix it with an underscore: `_x`
6+
...
7+
LL | trigger_unused_variables_macro!();
8+
| --------------------------------- in this macro invocation
9+
|
10+
note: the lint level is defined here
11+
--> $DIR/expect_lint_from_macro.rs:5:9
12+
|
13+
LL | #![warn(unused_variables)]
14+
| ^^^^^^^^^^^^^^^^
15+
= note: this warning originates in the macro `trigger_unused_variables_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
warning: unused variable: `x`
18+
--> $DIR/expect_lint_from_macro.rs:9:13
19+
|
20+
LL | let x = 0;
21+
| ^ help: if this is intentional, prefix it with an underscore: `_x`
22+
...
23+
LL | trigger_unused_variables_macro!();
24+
| --------------------------------- in this macro invocation
25+
|
26+
= note: this warning originates in the macro `trigger_unused_variables_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
27+
28+
warning: 2 warnings emitted
29+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// should error due to missing feature gate.
2+
3+
#![warn(unused)]
4+
5+
#[expect(unused)]
6+
//~^ ERROR: the `#[expect]` attribute is an experimental feature [E0658]
7+
fn main() {
8+
let x = 1;
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0658]: the `#[expect]` attribute is an experimental feature
2+
--> $DIR/expect_missing_feature_gate.rs:5:1
3+
|
4+
LL | #[expect(unused)]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
8+
= help: add `#![feature(lint_reasons)]` to the crate attributes to enable
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// check-pass
2+
3+
#![feature(lint_reasons)]
4+
5+
#![warn(unused)]
6+
7+
#[expect(unused_variables, unused_mut, while_true)]
8+
fn check_multiple_lints_1() {
9+
// This only trigger `unused_variables`
10+
let who_am_i = 666;
11+
}
12+
13+
#[expect(unused_variables, unused_mut, while_true)]
14+
fn check_multiple_lints_2() {
15+
// This only triggers `unused_mut`
16+
let mut x = 0;
17+
println!("I use x: {}", x);
18+
}
19+
20+
21+
#[expect(unused_variables, unused_mut, while_true)]
22+
fn check_multiple_lints_3() {
23+
// This only triggers `while_true` which is also an early lint
24+
while true {}
25+
}
26+
27+
fn main() {
28+
check_multiple_lints_1();
29+
check_multiple_lints_2();
30+
check_multiple_lints_3();
31+
}

0 commit comments

Comments
 (0)