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`
This commit is contained in:
parent
33a5945069
commit
a9bf9eaef5
18 changed files with 424 additions and 4 deletions
|
@ -16,11 +16,9 @@ pub fn check_expectations(tcx: TyCtxt<'_>) {
|
||||||
&tcx.lint_levels(()).lint_expectations;
|
&tcx.lint_levels(()).lint_expectations;
|
||||||
|
|
||||||
for (id, expectation) in lint_expectations {
|
for (id, expectation) in lint_expectations {
|
||||||
if fulfilled_expectations.contains(id) {
|
if !fulfilled_expectations.contains(id) {
|
||||||
continue;
|
emit_unfulfilled_expectation_lint(tcx, expectation);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_unfulfilled_expectation_lint(tcx, expectation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
// This expect attribute should catch all lint triggers
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
fn check_multiple_lints_1() {
|
||||||
|
let value_i = 0xff00ff;
|
||||||
|
let value_ii = 0xff00ff;
|
||||||
|
let value_iii = 0xff00ff;
|
||||||
|
let value_iiii = 0xff00ff;
|
||||||
|
let value_iiiii = 0xff00ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This expect attribute should catch all lint triggers
|
||||||
|
#[expect(unused_mut)]
|
||||||
|
fn check_multiple_lints_2() {
|
||||||
|
let mut a = 0xa;
|
||||||
|
let mut b = 0xb;
|
||||||
|
let mut c = 0xc;
|
||||||
|
println!("The ABC goes as: {:#x} {:#x} {:#x}", a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This expect attribute should catch all lint triggers
|
||||||
|
#[expect(while_true)]
|
||||||
|
fn check_multiple_lints_3() {
|
||||||
|
// `while_true` is an early lint
|
||||||
|
while true {}
|
||||||
|
|
||||||
|
while true {}
|
||||||
|
|
||||||
|
while true {}
|
||||||
|
|
||||||
|
while true {}
|
||||||
|
|
||||||
|
while true {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
check_multiple_lints_1();
|
||||||
|
check_multiple_lints_2();
|
||||||
|
check_multiple_lints_3();
|
||||||
|
}
|
15
src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs
Normal file
15
src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
#![expect(unused_mut)]
|
||||||
|
//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
|
||||||
|
//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
|
||||||
|
#![expect(unused_variables)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 0;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
warning: this lint expectation is unfulfilled
|
||||||
|
--> $DIR/crate_level_expect.rs:7:1
|
||||||
|
|
|
||||||
|
LL | #![expect(unused_mut)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
16
src/test/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs
Normal file
16
src/test/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
macro_rules! expect_inside_macro {
|
||||||
|
() => {
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
let x = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
expect_inside_macro!();
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
|
||||||
|
#![warn(unused_variables)]
|
||||||
|
|
||||||
|
macro_rules! trigger_unused_variables_macro {
|
||||||
|
() => {
|
||||||
|
let x = 0;
|
||||||
|
//~^ WARNING unused variable: `x` [unused_variables]
|
||||||
|
//~| WARNING unused variable: `x` [unused_variables]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_macro() {
|
||||||
|
// This should trigger the `unused_variables` from inside the macro
|
||||||
|
trigger_unused_variables_macro!();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should be fulfilled by the macro
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
pub fn check_expect_on_item() {
|
||||||
|
trigger_unused_variables_macro!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_expect_on_macro() {
|
||||||
|
// This should be fulfilled by the macro
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
trigger_unused_variables_macro!();
|
||||||
|
|
||||||
|
// FIXME: Lint attributes currently don't work directly on macros, and
|
||||||
|
// therefore also doesn't work for the new `expect` attribute. This bug
|
||||||
|
// is being tracked in rust#87391. The test will until then produce two
|
||||||
|
// warnings about the unused variable x.
|
||||||
|
//
|
||||||
|
// The expectation is still marked as fulfilled. I'm not totally why but
|
||||||
|
// my guess is that this will remain working when rust#87391 has been fixed.
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
warning: unused variable: `x`
|
||||||
|
--> $DIR/expect_lint_from_macro.rs:9:13
|
||||||
|
|
|
||||||
|
LL | let x = 0;
|
||||||
|
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||||
|
...
|
||||||
|
LL | trigger_unused_variables_macro!();
|
||||||
|
| --------------------------------- in this macro invocation
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/expect_lint_from_macro.rs:5:9
|
||||||
|
|
|
||||||
|
LL | #![warn(unused_variables)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
= note: this warning originates in the macro `trigger_unused_variables_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
warning: unused variable: `x`
|
||||||
|
--> $DIR/expect_lint_from_macro.rs:9:13
|
||||||
|
|
|
||||||
|
LL | let x = 0;
|
||||||
|
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||||
|
...
|
||||||
|
LL | trigger_unused_variables_macro!();
|
||||||
|
| --------------------------------- in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this warning originates in the macro `trigger_unused_variables_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
warning: 2 warnings emitted
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
// should error due to missing feature gate.
|
||||||
|
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
#[expect(unused)]
|
||||||
|
//~^ ERROR: the `#[expect]` attribute is an experimental feature [E0658]
|
||||||
|
fn main() {
|
||||||
|
let x = 1;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0658]: the `#[expect]` attribute is an experimental feature
|
||||||
|
--> $DIR/expect_missing_feature_gate.rs:5:1
|
||||||
|
|
|
||||||
|
LL | #[expect(unused)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
|
||||||
|
= help: add `#![feature(lint_reasons)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,31 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
#[expect(unused_variables, unused_mut, while_true)]
|
||||||
|
fn check_multiple_lints_1() {
|
||||||
|
// This only trigger `unused_variables`
|
||||||
|
let who_am_i = 666;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(unused_variables, unused_mut, while_true)]
|
||||||
|
fn check_multiple_lints_2() {
|
||||||
|
// This only triggers `unused_mut`
|
||||||
|
let mut x = 0;
|
||||||
|
println!("I use x: {}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[expect(unused_variables, unused_mut, while_true)]
|
||||||
|
fn check_multiple_lints_3() {
|
||||||
|
// This only triggers `while_true` which is also an early lint
|
||||||
|
while true {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
check_multiple_lints_1();
|
||||||
|
check_multiple_lints_2();
|
||||||
|
check_multiple_lints_3();
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// check-pass
|
||||||
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
#![warn(unused_mut)]
|
||||||
|
|
||||||
|
#[expect(
|
||||||
|
unused_mut,
|
||||||
|
reason = "this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered"
|
||||||
|
)]
|
||||||
|
//~^^^^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
|
||||||
|
//~| NOTE this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered
|
||||||
|
mod foo {
|
||||||
|
fn bar() {
|
||||||
|
#[allow(
|
||||||
|
unused_mut,
|
||||||
|
reason = "this overrides the previous `expect` lint level and allows the `unused_mut` lint here"
|
||||||
|
)]
|
||||||
|
let mut v = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(
|
||||||
|
unused_mut,
|
||||||
|
reason = "this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered"
|
||||||
|
)]
|
||||||
|
//~^^^^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
|
||||||
|
//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
//~| NOTE this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered
|
||||||
|
mod oof {
|
||||||
|
#[warn(
|
||||||
|
unused_mut,
|
||||||
|
//~^ NOTE the lint level is defined here
|
||||||
|
reason = "this overrides the previous `expect` lint level and warns about the `unused_mut` lint here"
|
||||||
|
)]
|
||||||
|
fn bar() {
|
||||||
|
let mut v = 0;
|
||||||
|
//~^ WARNING variable does not need to be mutable [unused_mut]
|
||||||
|
//~| NOTE this overrides the previous `expect` lint level and warns about the `unused_mut` lint here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,40 @@
|
||||||
|
warning: variable does not need to be mutable
|
||||||
|
--> $DIR/expect_nested_lint_levels.rs:37:13
|
||||||
|
|
|
||||||
|
LL | let mut v = 0;
|
||||||
|
| ----^
|
||||||
|
| |
|
||||||
|
| help: remove this `mut`
|
||||||
|
|
|
||||||
|
= note: this overrides the previous `expect` lint level and warns about the `unused_mut` lint here
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/expect_nested_lint_levels.rs:32:9
|
||||||
|
|
|
||||||
|
LL | unused_mut,
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
warning: this lint expectation is unfulfilled
|
||||||
|
--> $DIR/expect_nested_lint_levels.rs:23:1
|
||||||
|
|
|
||||||
|
LL | / #[expect(
|
||||||
|
LL | | unused_mut,
|
||||||
|
LL | | reason = "this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered"
|
||||||
|
LL | | )]
|
||||||
|
| |__^
|
||||||
|
|
|
||||||
|
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
= note: this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered
|
||||||
|
|
||||||
|
warning: this lint expectation is unfulfilled
|
||||||
|
--> $DIR/expect_nested_lint_levels.rs:7:1
|
||||||
|
|
|
||||||
|
LL | / #[expect(
|
||||||
|
LL | | unused_mut,
|
||||||
|
LL | | reason = "this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered"
|
||||||
|
LL | | )]
|
||||||
|
| |__^
|
||||||
|
|
|
||||||
|
= note: this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered
|
||||||
|
|
||||||
|
warning: 3 warnings emitted
|
||||||
|
|
11
src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs
Normal file
11
src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
#![expect(unused_variables, reason = "<This should fail and display this reason>")]
|
||||||
|
//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
|
||||||
|
//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
//~| NOTE <This should fail and display this reason>
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
warning: this lint expectation is unfulfilled
|
||||||
|
--> $DIR/expect_with_reason.rs:6:1
|
||||||
|
|
|
||||||
|
LL | #![expect(unused_variables, reason = "<This should fail and display this reason>")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
= note: <This should fail and display this reason>
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
|
||||||
|
fn expect_early_pass_lints() {
|
||||||
|
#[expect(while_true)]
|
||||||
|
while true {
|
||||||
|
println!("I never stop")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(unused_doc_comments)]
|
||||||
|
/// This comment triggers the `unused_doc_comments` lint
|
||||||
|
let _sheep = "wolf";
|
||||||
|
|
||||||
|
let x = 123;
|
||||||
|
#[expect(ellipsis_inclusive_range_patterns)]
|
||||||
|
match x {
|
||||||
|
0...100 => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
fn check_specific_lint() {
|
||||||
|
let x = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(unused)]
|
||||||
|
fn check_lint_group() {
|
||||||
|
let x = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
fn check_multiple_lint_emissions() {
|
||||||
|
let r = 1;
|
||||||
|
let u = 8;
|
||||||
|
let s = 2;
|
||||||
|
let t = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod check_multiple_expected_lints {
|
||||||
|
#[expect(unused_variables, unused_mut)]
|
||||||
|
pub fn check_lint_1() {
|
||||||
|
// unused_variables should fulfill the expectation
|
||||||
|
let c = 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(unused_variables, unused_mut)]
|
||||||
|
pub fn check_lint_2() {
|
||||||
|
// unused_mut should fulfill the expectation
|
||||||
|
let mut c = 17;
|
||||||
|
let _ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod check_fulfilled_expect_in_macro {
|
||||||
|
macro_rules! expect_inside_macro {
|
||||||
|
() => {
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
let x = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_macro() {
|
||||||
|
expect_inside_macro!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
check_specific_lint();
|
||||||
|
check_lint_group();
|
||||||
|
check_multiple_lint_emissions();
|
||||||
|
|
||||||
|
check_multiple_expected_lints::check_lint_1();
|
||||||
|
check_multiple_expected_lints::check_lint_2();
|
||||||
|
|
||||||
|
check_fulfilled_expect_in_macro::check_macro();
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(lint_reasons)]
|
||||||
|
#![warn(unused)]
|
||||||
|
|
||||||
|
#[warn(unused_variables)]
|
||||||
|
#[expect(unused_variables)]
|
||||||
|
//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
|
||||||
|
//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
#[expect(unused_variables)] // Only this expectation will be fulfilled
|
||||||
|
fn main() {
|
||||||
|
let x = 2;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
warning: this lint expectation is unfulfilled
|
||||||
|
--> $DIR/multiple_expect_attrs.rs:7:1
|
||||||
|
|
|
||||||
|
LL | #[expect(unused_variables)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue