From a9bf9eaef5165067414b33777a2c924e42aab5aa Mon Sep 17 00:00:00 2001 From: xFrednet Date: Fri, 6 Aug 2021 23:38:09 +0200 Subject: [PATCH] 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` --- compiler/rustc_lint/src/expect.rs | 6 +- .../catch_multiple_lint_triggers.rs | 45 ++++++++++++++ .../crate_level_expect.rs | 15 +++++ .../crate_level_expect.stderr | 10 +++ .../expect_inside_macro.rs | 16 +++++ .../expect_lint_from_macro.rs | 42 +++++++++++++ .../expect_lint_from_macro.stderr | 29 +++++++++ .../expect_missing_feature_gate.rs | 9 +++ .../expect_missing_feature_gate.stderr | 12 ++++ .../expect_multiple_lints.rs | 31 ++++++++++ .../expect_nested_lint_levels.rs | 43 +++++++++++++ .../expect_nested_lint_levels.stderr | 40 ++++++++++++ .../expect_with_reason.rs | 11 ++++ .../expect_with_reason.stderr | 11 ++++ .../fulfilled_expectation_early_lints.rs | 23 +++++++ .../fulfilled_expectation_late_lints.rs | 61 +++++++++++++++++++ .../multiple_expect_attrs.rs | 14 +++++ .../multiple_expect_attrs.stderr | 10 +++ 18 files changed, 424 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 49664322a98..db0756f5f54 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -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); } } diff --git a/src/test/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs b/src/test/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs new file mode 100644 index 00000000000..6b255b799b7 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs @@ -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(); +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs b/src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs new file mode 100644 index 00000000000..9f591ba9852 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs @@ -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; +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr b/src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr new file mode 100644 index 00000000000..757e6471c06 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr @@ -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 + diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs new file mode 100644 index 00000000000..b95815bc50b --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs @@ -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!(); +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs new file mode 100644 index 00000000000..07c60fa0c32 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs @@ -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() { + +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr new file mode 100644 index 00000000000..817e16fdcaa --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr @@ -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 + diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs new file mode 100644 index 00000000000..928e1610614 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs @@ -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; +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr new file mode 100644 index 00000000000..b5601cf9e65 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr @@ -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 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`. diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs new file mode 100644 index 00000000000..943150d2dbd --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs @@ -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(); +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs new file mode 100644 index 00000000000..f5f0a0bc591 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs @@ -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() {} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr new file mode 100644 index 00000000000..ed3e99d3386 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr @@ -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 + diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs new file mode 100644 index 00000000000..b4183d98211 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs @@ -0,0 +1,11 @@ +// check-pass + +#![feature(lint_reasons)] +#![warn(unused)] + +#![expect(unused_variables, reason = "")] +//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] +//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default +//~| NOTE + +fn main() {} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr new file mode 100644 index 00000000000..f1d90978f83 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr @@ -0,0 +1,11 @@ +warning: this lint expectation is unfulfilled + --> $DIR/expect_with_reason.rs:6:1 + | +LL | #![expect(unused_variables, reason = "")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unfulfilled_lint_expectations)]` on by default + = note: + +warning: 1 warning emitted + diff --git a/src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs b/src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs new file mode 100644 index 00000000000..6624b930e5e --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs @@ -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() {} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs b/src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs new file mode 100644 index 00000000000..b8182b5b620 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs @@ -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(); +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs b/src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs new file mode 100644 index 00000000000..98080b4e822 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs @@ -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; +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr b/src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr new file mode 100644 index 00000000000..79657eb5393 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr @@ -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 + -- 2.44.0