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:
xFrednet 2021-08-06 23:38:09 +02:00
parent 33a5945069
commit a9bf9eaef5
No known key found for this signature in database
GPG key ID: FCDCBF29AF64D601
18 changed files with 424 additions and 4 deletions

View file

@ -16,11 +16,9 @@ pub fn check_expectations(tcx: TyCtxt<'_>) {
&tcx.lint_levels(()).lint_expectations;
for (id, expectation) in lint_expectations {
if fulfilled_expectations.contains(id) {
continue;
if !fulfilled_expectations.contains(id) {
emit_unfulfilled_expectation_lint(tcx, expectation);
}
emit_unfulfilled_expectation_lint(tcx, expectation);
}
}

View file

@ -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();
}

View 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;
}

View file

@ -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

View 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!();
}

View file

@ -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() {
}

View file

@ -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

View file

@ -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;
}

View file

@ -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`.

View file

@ -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();
}

View file

@ -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() {}

View file

@ -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

View 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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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();
}

View file

@ -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;
}

View file

@ -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