]> git.lizzy.rs Git - rust.git/commitdiff
Add UI tests for the `expect` attribute (RFC-2383)
authorxFrednet <xFrednet@gmail.com>
Fri, 6 Aug 2021 21:38:09 +0000 (23:38 +0200)
committerxFrednet <xFrednet@gmail.com>
Wed, 2 Mar 2022 16:46:08 +0000 (17:46 +0100)
* 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`

18 files changed:
compiler/rustc_lint/src/expect.rs
src/test/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs [new file with mode: 0644]
src/test/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr [new file with mode: 0644]

index 49664322a98bf3125a61f68d3a79b19c72ab8944..db0756f5f54e2ef241bb20d2727c06bf54c80e81 100644 (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);
     }
 }
 
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 (file)
index 0000000..6b255b7
--- /dev/null
@@ -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 (file)
index 0000000..9f591ba
--- /dev/null
@@ -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 (file)
index 0000000..757e647
--- /dev/null
@@ -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 (file)
index 0000000..b95815b
--- /dev/null
@@ -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 (file)
index 0000000..07c60fa
--- /dev/null
@@ -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 (file)
index 0000000..817e16f
--- /dev/null
@@ -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 (file)
index 0000000..928e161
--- /dev/null
@@ -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 (file)
index 0000000..b5601cf
--- /dev/null
@@ -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`.
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 (file)
index 0000000..943150d
--- /dev/null
@@ -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 (file)
index 0000000..f5f0a0b
--- /dev/null
@@ -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 (file)
index 0000000..ed3e99d
--- /dev/null
@@ -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 (file)
index 0000000..b4183d9
--- /dev/null
@@ -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() {}
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 (file)
index 0000000..f1d9097
--- /dev/null
@@ -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
+
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 (file)
index 0000000..6624b93
--- /dev/null
@@ -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 (file)
index 0000000..b8182b5
--- /dev/null
@@ -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 (file)
index 0000000..98080b4
--- /dev/null
@@ -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 (file)
index 0000000..79657eb
--- /dev/null
@@ -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
+