diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/lint/unused | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/lint/unused')
102 files changed, 4827 insertions, 0 deletions
diff --git a/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs new file mode 100644 index 000000000..b76b4321d --- /dev/null +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs @@ -0,0 +1 @@ +pub fn foo() {} diff --git a/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs new file mode 100644 index 000000000..b76b4321d --- /dev/null +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs @@ -0,0 +1 @@ +pub fn foo() {} diff --git a/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs new file mode 100644 index 000000000..b76b4321d --- /dev/null +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs @@ -0,0 +1 @@ +pub fn foo() {} diff --git a/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/ui/lint/unused/issue-30730.rs b/src/test/ui/lint/unused/issue-30730.rs new file mode 100644 index 000000000..d6be90c81 --- /dev/null +++ b/src/test/ui/lint/unused/issue-30730.rs @@ -0,0 +1,5 @@ +#![warn(unused)] +#![deny(warnings)] +use std::thread; +//~^ ERROR: unused import +fn main() {} diff --git a/src/test/ui/lint/unused/issue-30730.stderr b/src/test/ui/lint/unused/issue-30730.stderr new file mode 100644 index 000000000..b299e99a3 --- /dev/null +++ b/src/test/ui/lint/unused/issue-30730.stderr @@ -0,0 +1,15 @@ +error: unused import: `std::thread` + --> $DIR/issue-30730.rs:3:5 + | +LL | use std::thread; + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-30730.rs:2:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unused_imports)]` implied by `#[deny(warnings)]` + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/issue-46576.rs b/src/test/ui/lint/unused/issue-46576.rs new file mode 100644 index 000000000..15f458f38 --- /dev/null +++ b/src/test/ui/lint/unused/issue-46576.rs @@ -0,0 +1,21 @@ +#![allow(dead_code)] +#![deny(unused_imports)] + +use std::fs::File; +use std::io::{BufRead, BufReader, Read}; +//~^ ERROR unused import: `BufRead` + +pub fn read_from_file(path: &str) { + let file = File::open(&path).unwrap(); + let mut reader = BufReader::new(file); + let mut s = String::new(); + reader.read_to_string(&mut s).unwrap(); +} + +pub fn read_lines(s: &str) { + for _line in s.lines() { + + } +} + +fn main() {} diff --git a/src/test/ui/lint/unused/issue-46576.stderr b/src/test/ui/lint/unused/issue-46576.stderr new file mode 100644 index 000000000..6f4d97068 --- /dev/null +++ b/src/test/ui/lint/unused/issue-46576.stderr @@ -0,0 +1,14 @@ +error: unused import: `BufRead` + --> $DIR/issue-46576.rs:5:15 + | +LL | use std::io::{BufRead, BufReader, Read}; + | ^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-46576.rs:2:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs new file mode 100644 index 000000000..4822a9b2c --- /dev/null +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs @@ -0,0 +1,88 @@ +// check-pass + +#![feature(box_patterns)] + +#![warn(unused)] // UI tests pass `-A unused` (#43896) + +struct SoulHistory { + corridors_of_light: usize, + hours_are_suns: bool, + endless_and_singing: bool +} + +struct LovelyAmbition { + lips: usize, + fire: usize +} + +#[derive(Clone, Copy)] +enum Large { + Suit { case: () } +} + +struct Tuple(Large, ()); + +fn main() { + let i_think_continually = 2; //~ WARNING unused variable: `i_think_continually` + let who_from_the_womb_remembered = SoulHistory { + corridors_of_light: 5, + hours_are_suns: true, + endless_and_singing: true + }; + + let mut mut_unused_var = 1; + //~^ WARNING unused variable: `mut_unused_var` + //~| WARNING variable does not need to be mutable + + let (mut var, unused_var) = (1, 2); + //~^ WARNING unused variable: `var` + //~| WARNING unused variable: `unused_var` + //~| WARNING variable does not need to be mutable + // NOTE: `var` comes after `unused_var` lexicographically yet the warning + // for `var` will be emitted before the one for `unused_var`. We use an + // `IndexMap` to ensure this is the case instead of a `BTreeMap`. + + if let SoulHistory { corridors_of_light, //~ WARNING unused variable: `corridors_of_light` + mut hours_are_suns, //~ WARNING `hours_are_suns` is assigned to, but + endless_and_singing: true } = who_from_the_womb_remembered { + hours_are_suns = false; //~ WARNING unused_assignments + } + + let the_spirit = LovelyAmbition { lips: 1, fire: 2 }; + let LovelyAmbition { lips, fire } = the_spirit; //~ WARNING unused variable: `fire` + println!("{}", lips); + + let bag = Large::Suit { + case: () + }; + + // Plain struct + match bag { + Large::Suit { case } => {} //~ WARNING unused variable: `case` + }; + + // Referenced struct + match &bag { + &Large::Suit { case } => {} //~ WARNING unused variable: `case` + }; + + // Boxed struct + match Box::new(bag) { + box Large::Suit { case } => {} //~ WARNING unused variable: `case` + }; + + // Tuple with struct + match (bag,) { + (Large::Suit { case },) => {} //~ WARNING unused variable: `case` + }; + + // Slice with struct + match [bag] { + [Large::Suit { case }] => {} //~ WARNING unused variable: `case` + }; + + // Tuple struct with struct + match Tuple(bag, ()) { + Tuple(Large::Suit { case }, ()) => {} //~ WARNING unused variable: `case` + }; +} diff --git a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr new file mode 100644 index 000000000..26fa6eb9b --- /dev/null +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr @@ -0,0 +1,116 @@ +warning: unused variable: `i_think_continually` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:26:9 + | +LL | let i_think_continually = 2; + | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_i_think_continually` + | +note: the lint level is defined here + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 + | +LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) + | ^^^^^^ + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: unused variable: `mut_unused_var` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:13 + | +LL | let mut mut_unused_var = 1; + | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var` + +warning: unused variable: `var` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:14 + | +LL | let (mut var, unused_var) = (1, 2); + | ^^^ help: if this is intentional, prefix it with an underscore: `_var` + +warning: unused variable: `unused_var` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:19 + | +LL | let (mut var, unused_var) = (1, 2); + | ^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_var` + +warning: unused variable: `corridors_of_light` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:26 + | +LL | if let SoulHistory { corridors_of_light, + | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` + +warning: variable `hours_are_suns` is assigned to, but never used + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:30 + | +LL | mut hours_are_suns, + | ^^^^^^^^^^^^^^ + | + = note: consider using `_hours_are_suns` instead + +warning: value assigned to `hours_are_suns` is never read + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:9 + | +LL | hours_are_suns = false; + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` + = help: maybe it is overwritten before being read? + +warning: unused variable: `fire` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:52:32 + | +LL | let LovelyAmbition { lips, fire } = the_spirit; + | ^^^^ help: try ignoring the field: `fire: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:61:23 + | +LL | Large::Suit { case } => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:66:24 + | +LL | &Large::Suit { case } => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:71:27 + | +LL | box Large::Suit { case } => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:76:24 + | +LL | (Large::Suit { case },) => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:81:24 + | +LL | [Large::Suit { case }] => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:86:29 + | +LL | Tuple(Large::Suit { case }, ()) => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: variable does not need to be mutable + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9 + | +LL | let mut mut_unused_var = 1; + | ----^^^^^^^^^^^^^^ + | | + | help: remove this `mut` + | + = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]` + +warning: variable does not need to be mutable + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10 + | +LL | let (mut var, unused_var) = (1, 2); + | ----^^^ + | | + | help: remove this `mut` + +warning: 16 warnings emitted + diff --git a/src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed b/src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed new file mode 100644 index 000000000..1350b7ca6 --- /dev/null +++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed @@ -0,0 +1,34 @@ +// run-rustfix + +#![deny(unused)] + +pub struct S { + pub f1: i32, +} + +pub struct Point { + pub x: i32, + pub y: i32, +} + +pub enum E { + Variant { field: String } +} + +pub fn foo(arg: &E) { + match arg { + E::Variant { field: _ } => (), //~ ERROR unused variable + } +} + +fn main() { + let s = S { f1: 123 }; + let S { f1: _ } = s; //~ ERROR unused variable + + let points = vec![Point { x: 1, y: 2 }]; + let _: i32 = points.iter().map(|Point { x: _, y }| y).sum(); //~ ERROR unused variable + + match (Point { x: 1, y: 2 }) { + Point { y, x: _ } => y, //~ ERROR unused variable + }; +} diff --git a/src/test/ui/lint/unused/issue-54180-unused-ref-field.rs b/src/test/ui/lint/unused/issue-54180-unused-ref-field.rs new file mode 100644 index 000000000..7b3392b60 --- /dev/null +++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.rs @@ -0,0 +1,34 @@ +// run-rustfix + +#![deny(unused)] + +pub struct S { + pub f1: i32, +} + +pub struct Point { + pub x: i32, + pub y: i32, +} + +pub enum E { + Variant { field: String } +} + +pub fn foo(arg: &E) { + match arg { + E::Variant { ref field } => (), //~ ERROR unused variable + } +} + +fn main() { + let s = S { f1: 123 }; + let S { ref f1 } = s; //~ ERROR unused variable + + let points = vec![Point { x: 1, y: 2 }]; + let _: i32 = points.iter().map(|Point { x, y }| y).sum(); //~ ERROR unused variable + + match (Point { x: 1, y: 2 }) { + Point { y, ref mut x } => y, //~ ERROR unused variable + }; +} diff --git a/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr new file mode 100644 index 000000000..c501aa25f --- /dev/null +++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr @@ -0,0 +1,33 @@ +error: unused variable: `field` + --> $DIR/issue-54180-unused-ref-field.rs:20:22 + | +LL | E::Variant { ref field } => (), + | ^^^^^^^^^ help: try ignoring the field: `field: _` + | +note: the lint level is defined here + --> $DIR/issue-54180-unused-ref-field.rs:3:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` + +error: unused variable: `x` + --> $DIR/issue-54180-unused-ref-field.rs:29:45 + | +LL | let _: i32 = points.iter().map(|Point { x, y }| y).sum(); + | ^ help: try ignoring the field: `x: _` + +error: unused variable: `f1` + --> $DIR/issue-54180-unused-ref-field.rs:26:13 + | +LL | let S { ref f1 } = s; + | ^^^^^^ help: try ignoring the field: `f1: _` + +error: unused variable: `x` + --> $DIR/issue-54180-unused-ref-field.rs:32:20 + | +LL | Point { y, ref mut x } => y, + | ^^^^^^^^^ help: try ignoring the field: `x: _` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed new file mode 100644 index 000000000..0b3fe9371 --- /dev/null +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed @@ -0,0 +1,106 @@ +// run-rustfix + +#![feature(box_patterns, stmt_expr_attributes)] + +#![allow( + dead_code, + ellipsis_inclusive_range_patterns, + irrefutable_let_patterns, + unreachable_patterns, + unused_mut, + unused_variables +)] +#![deny(unused_parens)] + +fn lint_on_top_level() { + let a = 0; //~ ERROR unnecessary parentheses around pattern + for a in 0..1 {} //~ ERROR unnecessary parentheses around pattern + if let a = 0 {} //~ ERROR unnecessary parentheses around pattern + while let a = 0 {} //~ ERROR unnecessary parentheses around pattern + fn foo(a: u8) {} //~ ERROR unnecessary parentheses around pattern + let _ = |a: u8| 0; //~ ERROR unnecessary parentheses around pattern +} + +fn _no_lint_attr() { + let _x = #[allow(dead_code)] (1 + 2); +} + +// Don't lint in these cases (#64106). +fn or_patterns_no_lint() { + match Box::new(0) { + box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`. + _ => {} + } + + match 0 { + x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`. + _ => {} + } + + if let &(0 | 1) = &0 {} // Should also not lint. + if let &mut (0 | 1) = &mut 0 {} // Same. + + fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now. + + let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or. +} + +fn or_patterns_will_lint() { + if let 0 | 1 = 0 {} //~ ERROR unnecessary parentheses around pattern + if let (0 | 1,) = (0,) {} //~ ERROR unnecessary parentheses around pattern + if let [0 | 1] = [0] {} //~ ERROR unnecessary parentheses around pattern + if let 0 | 1 | 2 = 0 {} //~ ERROR unnecessary parentheses around pattern + struct TS(u8); + if let TS(0 | 1) = TS(0) {} //~ ERROR unnecessary parentheses around pattern + struct NS { f: u8 } + if let NS { f: 0 | 1 } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern +} + +// Don't lint on `&(mut x)` because `&mut x` means something else (#55342). +fn deref_mut_binding_no_lint() { + let &(mut x) = &0; +} + +fn main() { + match 1 { + _ => {} //~ ERROR unnecessary parentheses around pattern + y => {} //~ ERROR unnecessary parentheses around pattern + ref r => {} //~ ERROR unnecessary parentheses around pattern + e @ 1...2 => {} //~ ERROR unnecessary parentheses around pattern + (1...2) => {} // Non ambiguous range pattern should not warn + e @ (3...4) => {} // Non ambiguous range pattern should not warn + } + + match &1 { + e @ &(1...2) => {} //~ ERROR unnecessary parentheses around pattern + &_ => {} //~ ERROR unnecessary parentheses around pattern + e @ &(1...2) => {} // Ambiguous range pattern should not warn + &(1...2) => {} // Ambiguous range pattern should not warn + } + + match &1 { + e @ &(1...2) | e @ &(3...4) => {} // Complex ambiguous pattern should not warn + &_ => {} + } + + match 1 { + _ => {} //~ ERROR unnecessary parentheses around pattern + y => {} //~ ERROR unnecessary parentheses around pattern + ref r => {} //~ ERROR unnecessary parentheses around pattern + e @ 1..=2 => {} //~ ERROR unnecessary parentheses around pattern + (1..=2) => {} // Non ambiguous range pattern should not warn + e @ (3..=4) => {} // Non ambiguous range pattern should not warn + } + + match &1 { + e @ &(1..=2) => {} //~ ERROR unnecessary parentheses around pattern + &_ => {} //~ ERROR unnecessary parentheses around pattern + e @ &(1..=2) => {} // Ambiguous range pattern should not warn + &(1..=2) => {} // Ambiguous range pattern should not warn + } + + match &1 { + e @ &(1..=2) | e @ &(3..=4) => {} // Complex ambiguous pattern should not warn + &_ => {} + } +} diff --git a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs new file mode 100644 index 000000000..1e78ec5f7 --- /dev/null +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs @@ -0,0 +1,106 @@ +// run-rustfix + +#![feature(box_patterns, stmt_expr_attributes)] + +#![allow( + dead_code, + ellipsis_inclusive_range_patterns, + irrefutable_let_patterns, + unreachable_patterns, + unused_mut, + unused_variables +)] +#![deny(unused_parens)] + +fn lint_on_top_level() { + let (a) = 0; //~ ERROR unnecessary parentheses around pattern + for (a) in 0..1 {} //~ ERROR unnecessary parentheses around pattern + if let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern + while let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern + fn foo((a): u8) {} //~ ERROR unnecessary parentheses around pattern + let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern +} + +fn _no_lint_attr() { + let _x = #[allow(dead_code)] (1 + 2); +} + +// Don't lint in these cases (#64106). +fn or_patterns_no_lint() { + match Box::new(0) { + box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`. + _ => {} + } + + match 0 { + x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`. + _ => {} + } + + if let &(0 | 1) = &0 {} // Should also not lint. + if let &mut (0 | 1) = &mut 0 {} // Same. + + fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now. + + let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or. +} + +fn or_patterns_will_lint() { + if let (0 | 1) = 0 {} //~ ERROR unnecessary parentheses around pattern + if let ((0 | 1),) = (0,) {} //~ ERROR unnecessary parentheses around pattern + if let [(0 | 1)] = [0] {} //~ ERROR unnecessary parentheses around pattern + if let 0 | (1 | 2) = 0 {} //~ ERROR unnecessary parentheses around pattern + struct TS(u8); + if let TS((0 | 1)) = TS(0) {} //~ ERROR unnecessary parentheses around pattern + struct NS { f: u8 } + if let NS { f: (0 | 1) } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern +} + +// Don't lint on `&(mut x)` because `&mut x` means something else (#55342). +fn deref_mut_binding_no_lint() { + let &(mut x) = &0; +} + +fn main() { + match 1 { + (_) => {} //~ ERROR unnecessary parentheses around pattern + (y) => {} //~ ERROR unnecessary parentheses around pattern + (ref r) => {} //~ ERROR unnecessary parentheses around pattern + (e @ 1...2) => {} //~ ERROR unnecessary parentheses around pattern + (1...2) => {} // Non ambiguous range pattern should not warn + e @ (3...4) => {} // Non ambiguous range pattern should not warn + } + + match &1 { + (e @ &(1...2)) => {} //~ ERROR unnecessary parentheses around pattern + &(_) => {} //~ ERROR unnecessary parentheses around pattern + e @ &(1...2) => {} // Ambiguous range pattern should not warn + &(1...2) => {} // Ambiguous range pattern should not warn + } + + match &1 { + e @ &(1...2) | e @ &(3...4) => {} // Complex ambiguous pattern should not warn + &_ => {} + } + + match 1 { + (_) => {} //~ ERROR unnecessary parentheses around pattern + (y) => {} //~ ERROR unnecessary parentheses around pattern + (ref r) => {} //~ ERROR unnecessary parentheses around pattern + (e @ 1..=2) => {} //~ ERROR unnecessary parentheses around pattern + (1..=2) => {} // Non ambiguous range pattern should not warn + e @ (3..=4) => {} // Non ambiguous range pattern should not warn + } + + match &1 { + (e @ &(1..=2)) => {} //~ ERROR unnecessary parentheses around pattern + &(_) => {} //~ ERROR unnecessary parentheses around pattern + e @ &(1..=2) => {} // Ambiguous range pattern should not warn + &(1..=2) => {} // Ambiguous range pattern should not warn + } + + match &1 { + e @ &(1..=2) | e @ &(3..=4) => {} // Complex ambiguous pattern should not warn + &_ => {} + } +} diff --git a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr new file mode 100644 index 000000000..c73884663 --- /dev/null +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr @@ -0,0 +1,295 @@ +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:16:9 + | +LL | let (a) = 0; + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-54538-unused-parens-lint.rs:13:9 + | +LL | #![deny(unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - let (a) = 0; +LL + let a = 0; + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:17:9 + | +LL | for (a) in 0..1 {} + | ^ ^ + | +help: remove these parentheses + | +LL - for (a) in 0..1 {} +LL + for a in 0..1 {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:18:12 + | +LL | if let (a) = 0 {} + | ^ ^ + | +help: remove these parentheses + | +LL - if let (a) = 0 {} +LL + if let a = 0 {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:19:15 + | +LL | while let (a) = 0 {} + | ^ ^ + | +help: remove these parentheses + | +LL - while let (a) = 0 {} +LL + while let a = 0 {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:20:12 + | +LL | fn foo((a): u8) {} + | ^ ^ + | +help: remove these parentheses + | +LL - fn foo((a): u8) {} +LL + fn foo(a: u8) {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:21:14 + | +LL | let _ = |(a): u8| 0; + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = |(a): u8| 0; +LL + let _ = |a: u8| 0; + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:49:12 + | +LL | if let (0 | 1) = 0 {} + | ^ ^ + | +help: remove these parentheses + | +LL - if let (0 | 1) = 0 {} +LL + if let 0 | 1 = 0 {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:50:13 + | +LL | if let ((0 | 1),) = (0,) {} + | ^ ^ + | +help: remove these parentheses + | +LL - if let ((0 | 1),) = (0,) {} +LL + if let (0 | 1,) = (0,) {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:51:13 + | +LL | if let [(0 | 1)] = [0] {} + | ^ ^ + | +help: remove these parentheses + | +LL - if let [(0 | 1)] = [0] {} +LL + if let [0 | 1] = [0] {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:52:16 + | +LL | if let 0 | (1 | 2) = 0 {} + | ^ ^ + | +help: remove these parentheses + | +LL - if let 0 | (1 | 2) = 0 {} +LL + if let 0 | 1 | 2 = 0 {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:54:15 + | +LL | if let TS((0 | 1)) = TS(0) {} + | ^ ^ + | +help: remove these parentheses + | +LL - if let TS((0 | 1)) = TS(0) {} +LL + if let TS(0 | 1) = TS(0) {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:56:20 + | +LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {} + | ^ ^ + | +help: remove these parentheses + | +LL - if let NS { f: (0 | 1) } = (NS { f: 0 }) {} +LL + if let NS { f: 0 | 1 } = (NS { f: 0 }) {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:66:9 + | +LL | (_) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (_) => {} +LL + _ => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:67:9 + | +LL | (y) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (y) => {} +LL + y => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:68:9 + | +LL | (ref r) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (ref r) => {} +LL + ref r => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:69:9 + | +LL | (e @ 1...2) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ 1...2) => {} +LL + e @ 1...2 => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:75:9 + | +LL | (e @ &(1...2)) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ &(1...2)) => {} +LL + e @ &(1...2) => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:76:10 + | +LL | &(_) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - &(_) => {} +LL + &_ => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:87:9 + | +LL | (_) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (_) => {} +LL + _ => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:88:9 + | +LL | (y) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (y) => {} +LL + y => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:89:9 + | +LL | (ref r) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (ref r) => {} +LL + ref r => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:90:9 + | +LL | (e @ 1..=2) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ 1..=2) => {} +LL + e @ 1..=2 => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:96:9 + | +LL | (e @ &(1..=2)) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ &(1..=2)) => {} +LL + e @ &(1..=2) => {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:97:10 + | +LL | &(_) => {} + | ^ ^ + | +help: remove these parentheses + | +LL - &(_) => {} +LL + &_ => {} + | + +error: aborting due to 24 previous errors + diff --git a/src/test/ui/lint/unused/issue-59896.rs b/src/test/ui/lint/unused/issue-59896.rs new file mode 100644 index 000000000..ff9f19acf --- /dev/null +++ b/src/test/ui/lint/unused/issue-59896.rs @@ -0,0 +1,9 @@ +#![deny(unused_imports)] + +struct S; + +fn main() { + use S; //~ ERROR the item `S` is imported redundantly + + let _s = S; +} diff --git a/src/test/ui/lint/unused/issue-59896.stderr b/src/test/ui/lint/unused/issue-59896.stderr new file mode 100644 index 000000000..95b7938ae --- /dev/null +++ b/src/test/ui/lint/unused/issue-59896.stderr @@ -0,0 +1,17 @@ +error: the item `S` is imported redundantly + --> $DIR/issue-59896.rs:6:9 + | +LL | struct S; + | --------- the item `S` is already defined here +... +LL | use S; + | ^ + | +note: the lint level is defined here + --> $DIR/issue-59896.rs:1:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs new file mode 100644 index 000000000..e3631d014 --- /dev/null +++ b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs @@ -0,0 +1,85 @@ +// FIXME: should be run-rustfix, but rustfix doesn't currently support multipart suggestions, see +// #53934 + +#![deny(unused)] + +pub enum MyEnum { + A { i: i32, j: i32 }, + B { i: i32, j: i32 }, +} + +pub enum MixedEnum { + A { i: i32 }, + B(i32), +} + +pub fn no_ref(x: MyEnum) { + use MyEnum::*; + + match x { + A { i, j } | B { i, j } => { //~ ERROR unused variable + println!("{}", i); + } + } +} + +pub fn with_ref(x: MyEnum) { + use MyEnum::*; + + match x { + A { i, ref j } | B { i, ref j } => { //~ ERROR unused variable + println!("{}", i); + } + } +} + +pub fn inner_no_ref(x: Option<MyEnum>) { + use MyEnum::*; + + match x { + Some(A { i, j } | B { i, j }) => { //~ ERROR unused variable + println!("{}", i); + } + + _ => {} + } +} + +pub fn inner_with_ref(x: Option<MyEnum>) { + use MyEnum::*; + + match x { + Some(A { i, ref j } | B { i, ref j }) => { //~ ERROR unused variable + println!("{}", i); + } + + _ => {} + } +} + +pub fn mixed_no_ref(x: MixedEnum) { + match x { + MixedEnum::A { i } | MixedEnum::B(i) => { //~ ERROR unused variable + println!("match"); + } + } +} + +pub fn mixed_with_ref(x: MixedEnum) { + match x { + MixedEnum::A { ref i } | MixedEnum::B(ref i) => { //~ ERROR unused variable + println!("match"); + } + } +} + +pub fn main() { + no_ref(MyEnum::A { i: 1, j: 2 }); + with_ref(MyEnum::A { i: 1, j: 2 }); + + inner_no_ref(Some(MyEnum::A { i: 1, j: 2 })); + inner_with_ref(Some(MyEnum::A { i: 1, j: 2 })); + + mixed_no_ref(MixedEnum::B(5)); + mixed_with_ref(MixedEnum::B(5)); +} diff --git a/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr new file mode 100644 index 000000000..8fc2d1bc8 --- /dev/null +++ b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr @@ -0,0 +1,74 @@ +error: unused variable: `j` + --> $DIR/issue-67691-unused-field-in-or-pattern.rs:20:16 + | +LL | A { i, j } | B { i, j } => { + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-67691-unused-field-in-or-pattern.rs:4:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` +help: try ignoring the field + | +LL | A { i, j: _ } | B { i, j: _ } => { + | ~~~~ ~~~~ + +error: unused variable: `j` + --> $DIR/issue-67691-unused-field-in-or-pattern.rs:30:16 + | +LL | A { i, ref j } | B { i, ref j } => { + | ^^^^^ ^^^^^ + | +help: try ignoring the field + | +LL | A { i, j: _ } | B { i, j: _ } => { + | ~~~~ ~~~~ + +error: unused variable: `j` + --> $DIR/issue-67691-unused-field-in-or-pattern.rs:40:21 + | +LL | Some(A { i, j } | B { i, j }) => { + | ^ ^ + | +help: try ignoring the field + | +LL | Some(A { i, j: _ } | B { i, j: _ }) => { + | ~~~~ ~~~~ + +error: unused variable: `j` + --> $DIR/issue-67691-unused-field-in-or-pattern.rs:52:21 + | +LL | Some(A { i, ref j } | B { i, ref j }) => { + | ^^^^^ ^^^^^ + | +help: try ignoring the field + | +LL | Some(A { i, j: _ } | B { i, j: _ }) => { + | ~~~~ ~~~~ + +error: unused variable: `i` + --> $DIR/issue-67691-unused-field-in-or-pattern.rs:62:24 + | +LL | MixedEnum::A { i } | MixedEnum::B(i) => { + | ^ ^ + | +help: try ignoring the field + | +LL | MixedEnum::A { i: _ } | MixedEnum::B(_) => { + | ~~~~ ~ + +error: unused variable: `i` + --> $DIR/issue-67691-unused-field-in-or-pattern.rs:70:24 + | +LL | MixedEnum::A { ref i } | MixedEnum::B(ref i) => { + | ^^^^^ ^^^^^ + | +help: try ignoring the field + | +LL | MixedEnum::A { i: _ } | MixedEnum::B(_) => { + | ~~~~ ~ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/lint/unused/issue-70041.rs b/src/test/ui/lint/unused/issue-70041.rs new file mode 100644 index 000000000..22e42295e --- /dev/null +++ b/src/test/ui/lint/unused/issue-70041.rs @@ -0,0 +1,13 @@ +// compile-flags: --edition=2018 +// run-pass + +macro_rules! regex { + //~^ WARN unused macro definition + () => {}; +} + +#[allow(dead_code)] +use regex; +//~^ WARN unused import + +fn main() {} diff --git a/src/test/ui/lint/unused/issue-70041.stderr b/src/test/ui/lint/unused/issue-70041.stderr new file mode 100644 index 000000000..b2e6d1aeb --- /dev/null +++ b/src/test/ui/lint/unused/issue-70041.stderr @@ -0,0 +1,18 @@ +warning: unused macro definition: `regex` + --> $DIR/issue-70041.rs:4:14 + | +LL | macro_rules! regex { + | ^^^^^ + | + = note: `#[warn(unused_macros)]` on by default + +warning: unused import: `regex` + --> $DIR/issue-70041.rs:10:5 + | +LL | use regex; + | ^^^^^ + | + = note: `#[warn(unused_imports)]` on by default + +warning: 2 warnings emitted + diff --git a/src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs b/src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs new file mode 100644 index 000000000..24d77e36d --- /dev/null +++ b/src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs @@ -0,0 +1,23 @@ +// check-pass +// Make sure unused parens lint doesn't emit a false positive. +// See https://github.com/rust-lang/rust/issues/71290 for details. +#![deny(unused_parens)] + +fn x() -> u8 { + ({ 0 }) + 1 +} + +fn y() -> u8 { + ({ 0 } + 1) +} + +pub fn foo(a: bool, b: bool) -> u8 { + (if a { 1 } else { 0 } + if b { 1 } else { 0 }) +} + +pub fn bar() -> u8 { + // Make sure nested expressions are handled correctly as well + ({ 0 } + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9) +} + +fn main() {} diff --git a/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs new file mode 100644 index 000000000..8064c3a88 --- /dev/null +++ b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs @@ -0,0 +1,26 @@ +#![feature(generator_trait)] +#![feature(generators)] +#![deny(unused_braces, unused_parens)] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let mut x = |_| { + while let Some(_) = (yield) {} + while let Some(_) = {yield} {} + + // Only warn these cases + while let Some(_) = ({yield}) {} //~ ERROR: unnecessary parentheses + while let Some(_) = ((yield)) {} //~ ERROR: unnecessary parentheses + {{yield}}; //~ ERROR: unnecessary braces + {( yield )}; //~ ERROR: unnecessary parentheses + while let Some(_) = {(yield)} {} //~ ERROR: unnecessary parentheses + while let Some(_) = {{yield}} {} //~ ERROR: unnecessary braces + + // FIXME: It'd be great if we could also warn them. + ((yield)); + ({ yield }); + }; + let _ = Pin::new(&mut x).resume(Some(5)); +} diff --git a/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr new file mode 100644 index 000000000..3f1fee332 --- /dev/null +++ b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr @@ -0,0 +1,84 @@ +error: unnecessary parentheses around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:14:29 + | +LL | while let Some(_) = ({yield}) {} + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:24 + | +LL | #![deny(unused_braces, unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - while let Some(_) = ({yield}) {} +LL + while let Some(_) = {yield} {} + | + +error: unnecessary parentheses around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:15:29 + | +LL | while let Some(_) = ((yield)) {} + | ^ ^ + | +help: remove these parentheses + | +LL - while let Some(_) = ((yield)) {} +LL + while let Some(_) = (yield) {} + | + +error: unnecessary braces around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:16:10 + | +LL | {{yield}}; + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:9 + | +LL | #![deny(unused_braces, unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these braces + | +LL - {{yield}}; +LL + {yield}; + | + +error: unnecessary parentheses around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:17:10 + | +LL | {( yield )}; + | ^^ ^^ + | +help: remove these parentheses + | +LL - {( yield )}; +LL + {yield}; + | + +error: unnecessary parentheses around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:18:30 + | +LL | while let Some(_) = {(yield)} {} + | ^ ^ + | +help: remove these parentheses + | +LL - while let Some(_) = {(yield)} {} +LL + while let Some(_) = {yield} {} + | + +error: unnecessary braces around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:19:30 + | +LL | while let Some(_) = {{yield}} {} + | ^ ^ + | +help: remove these braces + | +LL - while let Some(_) = {{yield}} {} +LL + while let Some(_) = {yield} {} + | + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed b/src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed new file mode 100644 index 000000000..aac918f2b --- /dev/null +++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed @@ -0,0 +1,12 @@ +// run-rustfix +// Regression test for #81314: Unused variable lint should +// span only the identifier and not the rest of the pattern + +#![deny(unused)] + +fn main() { + let [_rest @ ..] = [1, 2, 3]; //~ ERROR unused variable +} + +pub fn foo([_rest @ ..]: &[i32]) { //~ ERROR unused variable +} diff --git a/src/test/ui/lint/unused/issue-81314-unused-span-ident.rs b/src/test/ui/lint/unused/issue-81314-unused-span-ident.rs new file mode 100644 index 000000000..78296f425 --- /dev/null +++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.rs @@ -0,0 +1,12 @@ +// run-rustfix +// Regression test for #81314: Unused variable lint should +// span only the identifier and not the rest of the pattern + +#![deny(unused)] + +fn main() { + let [rest @ ..] = [1, 2, 3]; //~ ERROR unused variable +} + +pub fn foo([rest @ ..]: &[i32]) { //~ ERROR unused variable +} diff --git a/src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr b/src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr new file mode 100644 index 000000000..519c71e94 --- /dev/null +++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr @@ -0,0 +1,21 @@ +error: unused variable: `rest` + --> $DIR/issue-81314-unused-span-ident.rs:8:10 + | +LL | let [rest @ ..] = [1, 2, 3]; + | ^^^^ help: if this is intentional, prefix it with an underscore: `_rest` + | +note: the lint level is defined here + --> $DIR/issue-81314-unused-span-ident.rs:5:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` + +error: unused variable: `rest` + --> $DIR/issue-81314-unused-span-ident.rs:11:13 + | +LL | pub fn foo([rest @ ..]: &[i32]) { + | ^^^^ help: if this is intentional, prefix it with an underscore: `_rest` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/unused/issue-85913.rs b/src/test/ui/lint/unused/issue-85913.rs new file mode 100644 index 000000000..7f3817b6e --- /dev/null +++ b/src/test/ui/lint/unused/issue-85913.rs @@ -0,0 +1,13 @@ +#![deny(unused_must_use)] + +pub fn fun() -> i32 { + function() && return 1; + //~^ ERROR: unused logical operation that must be used + return 0; +} + +fn function() -> bool { + true +} + +fn main() {} diff --git a/src/test/ui/lint/unused/issue-85913.stderr b/src/test/ui/lint/unused/issue-85913.stderr new file mode 100644 index 000000000..8234ed3b1 --- /dev/null +++ b/src/test/ui/lint/unused/issue-85913.stderr @@ -0,0 +1,18 @@ +error: unused logical operation that must be used + --> $DIR/issue-85913.rs:4:5 + | +LL | function() && return 1; + | ^^^^^^^^^^^^^^^^^^^^^^ the logical operation produces a value + | +note: the lint level is defined here + --> $DIR/issue-85913.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = function() && return 1; + | +++++++ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/issue-88519-unused-paren.rs b/src/test/ui/lint/unused/issue-88519-unused-paren.rs new file mode 100644 index 000000000..be02fcd3f --- /dev/null +++ b/src/test/ui/lint/unused/issue-88519-unused-paren.rs @@ -0,0 +1,94 @@ +// check-pass +// Make sure unused parens lint doesn't emit a false positive. +// See https://github.com/rust-lang/rust/issues/88519 +#![deny(unused_parens)] +#![feature(type_ascription)] + +// binary ops are tested in issue-71290-unused-paren-binop.rs + +mod call { + fn noop() -> u8 { 0 } + fn outside() -> u8 { + ({ noop })() + } + fn inside() -> u8 { + ({ noop }()) + } + fn outside_match() -> u8 { + (match noop { x => x })() + } + fn inside_match() -> u8 { + (match noop { x => x }()) + } + fn outside_if() -> u8 { + (if false { noop } else { noop })() + } + fn inside_if() -> u8 { + (if false { noop } else { noop }()) + } +} + +mod casts { + fn outside() -> u8 { + ({ 0 }) as u8 + } + fn inside() -> u8 { + ({ 0 } as u8) + } + fn outside_match() -> u8 { + (match 0 { x => x }) as u8 + } + fn inside_match() -> u8 { + (match 0 { x => x } as u8) + } + fn outside_if() -> u8 { + (if false { 0 } else { 0 }) as u8 + } + fn inside_if() -> u8 { + (if false { 0 } else { 0 } as u8) + } +} + +mod typeascription { + fn outside() -> u8 { + ({ 0 }): u8 + } + fn inside() -> u8 { + ({ 0 }: u8) + } + fn outside_match() -> u8 { + (match 0 { x => x }): u8 + } + fn inside_match() -> u8 { + (match 0 { x => x }: u8) + } + fn outside_if() -> u8 { + (if false { 0 } else { 0 }): u8 + } + fn inside_if() -> u8 { + (if false { 0 } else { 0 }: u8) + } +} + +mod index { + fn outside(x: &[u8]) -> u8 { + ({ x })[0] + } + fn inside(x: &[u8]) -> u8 { + ({ x }[0]) + } + fn outside_match(x: &[u8]) -> u8 { + (match x { x => x })[0] + } + fn inside_match(x: &[u8]) -> u8 { + (match x { x => x }[0]) + } + fn outside_if(x: &[u8]) -> u8 { + (if false { x } else { x })[0] + } + fn inside_if(x: &[u8]) -> u8 { + (if false { x } else { x }[0]) + } +} + +fn main() {} diff --git a/src/test/ui/lint/unused/issue-90807-unused-paren-error.rs b/src/test/ui/lint/unused/issue-90807-unused-paren-error.rs new file mode 100644 index 000000000..2fca2e262 --- /dev/null +++ b/src/test/ui/lint/unused/issue-90807-unused-paren-error.rs @@ -0,0 +1,9 @@ +// Make sure unused parens lint emit is emitted for loop and match. +// See https://github.com/rust-lang/rust/issues/90807 +// and https://github.com/rust-lang/rust/pull/91956#discussion_r771647953 +#![deny(unused_parens)] + +fn main() { + for _ in (1..loop { break 2 }) {} //~ERROR + for _ in (1..match () { () => 2 }) {} //~ERROR +} diff --git a/src/test/ui/lint/unused/issue-90807-unused-paren-error.stderr b/src/test/ui/lint/unused/issue-90807-unused-paren-error.stderr new file mode 100644 index 000000000..b3b809d5f --- /dev/null +++ b/src/test/ui/lint/unused/issue-90807-unused-paren-error.stderr @@ -0,0 +1,31 @@ +error: unnecessary parentheses around `for` iterator expression + --> $DIR/issue-90807-unused-paren-error.rs:7:14 + | +LL | for _ in (1..loop { break 2 }) {} + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-90807-unused-paren-error.rs:4:9 + | +LL | #![deny(unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - for _ in (1..loop { break 2 }) {} +LL + for _ in 1..loop { break 2 } {} + | + +error: unnecessary parentheses around `for` iterator expression + --> $DIR/issue-90807-unused-paren-error.rs:8:14 + | +LL | for _ in (1..match () { () => 2 }) {} + | ^ ^ + | +help: remove these parentheses + | +LL - for _ in (1..match () { () => 2 }) {} +LL + for _ in 1..match () { () => 2 } {} + | + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/unused/issue-90807-unused-paren.rs b/src/test/ui/lint/unused/issue-90807-unused-paren.rs new file mode 100644 index 000000000..4c0930f96 --- /dev/null +++ b/src/test/ui/lint/unused/issue-90807-unused-paren.rs @@ -0,0 +1,8 @@ +// check-pass +// Make sure unused parens lint doesn't emit a false positive. +// See https://github.com/rust-lang/rust/issues/90807 +#![deny(unused_parens)] + +fn main() { + for _ in (1..{ 2 }) {} +} diff --git a/src/test/ui/lint/unused/issue-92751.rs b/src/test/ui/lint/unused/issue-92751.rs new file mode 100644 index 000000000..2fb292736 --- /dev/null +++ b/src/test/ui/lint/unused/issue-92751.rs @@ -0,0 +1,9 @@ +#[deny(unused)] +pub fn broken(x: Option<()>) -> i32 { + match x { + Some(()) => (1), //~ ERROR unnecessary parentheses around match arm expression + None => (2), //~ ERROR unnecessary parentheses around match arm expression + } +} + +fn main() { } diff --git a/src/test/ui/lint/unused/issue-92751.stderr b/src/test/ui/lint/unused/issue-92751.stderr new file mode 100644 index 000000000..0a8d8e672 --- /dev/null +++ b/src/test/ui/lint/unused/issue-92751.stderr @@ -0,0 +1,32 @@ +error: unnecessary parentheses around match arm expression + --> $DIR/issue-92751.rs:4:21 + | +LL | Some(()) => (1), + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-92751.rs:1:8 + | +LL | #[deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_parens)]` implied by `#[deny(unused)]` +help: remove these parentheses + | +LL - Some(()) => (1), +LL + Some(()) => 1, + | + +error: unnecessary parentheses around match arm expression + --> $DIR/issue-92751.rs:5:17 + | +LL | None => (2), + | ^ ^ + | +help: remove these parentheses + | +LL - None => (2), +LL + None => 2, + | + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/unused/lint-unused-extern-crate.rs b/src/test/ui/lint/unused/lint-unused-extern-crate.rs new file mode 100644 index 000000000..d5e4da526 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-extern-crate.rs @@ -0,0 +1,35 @@ +// aux-build:lint_unused_extern_crate.rs +// aux-build:lint_unused_extern_crate2.rs +// aux-build:lint_unused_extern_crate3.rs +// aux-build:lint_unused_extern_crate4.rs +// aux-build:lint_unused_extern_crate5.rs + +#![deny(unused_extern_crates)] +#![allow(unused_variables)] +#![allow(deprecated)] + +extern crate lint_unused_extern_crate5; //~ ERROR: unused extern crate + +pub extern crate lint_unused_extern_crate4; // no error, it is re-exported + +extern crate lint_unused_extern_crate3; // no error, it is used + +extern crate lint_unused_extern_crate2; // no error, the use marks it as used + // even if imported objects aren't used + +extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used + +#[allow(unused_imports)] +use lint_unused_extern_crate2::foo as bar; + +use other::*; + +mod foo { + // Test that this is unused even though an earlier `extern crate` is used. + extern crate lint_unused_extern_crate2; //~ ERROR unused extern crate +} + +fn main() { + lint_unused_extern_crate3::foo(); + let y = foo(); +} diff --git a/src/test/ui/lint/unused/lint-unused-extern-crate.stderr b/src/test/ui/lint/unused/lint-unused-extern-crate.stderr new file mode 100644 index 000000000..46d8f3bee --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-extern-crate.stderr @@ -0,0 +1,20 @@ +error: unused extern crate + --> $DIR/lint-unused-extern-crate.rs:11:1 + | +LL | extern crate lint_unused_extern_crate5; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it + | +note: the lint level is defined here + --> $DIR/lint-unused-extern-crate.rs:7:9 + | +LL | #![deny(unused_extern_crates)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unused extern crate + --> $DIR/lint-unused-extern-crate.rs:29:5 + | +LL | extern crate lint_unused_extern_crate2; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/unused/lint-unused-imports.rs b/src/test/ui/lint/unused/lint-unused-imports.rs new file mode 100644 index 000000000..4754d8880 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-imports.rs @@ -0,0 +1,90 @@ +#![deny(unused_imports)] +#![allow(dead_code)] + +use bar::c::cc as cal; + +use std::mem::*; // shouldn't get errors for not using + // everything imported +use std::fmt::{}; +//~^ ERROR unused import: `std::fmt::{}` + +// Should get errors for both 'Some' and 'None' +use std::option::Option::{Some, None}; +//~^ ERROR unused imports: `None`, `Some` + +use test::A; //~ ERROR unused import: `test::A` +// Be sure that if we just bring some methods into scope that they're also +// counted as being used. +use test::B; +// But only when actually used: do not get confused by the method with the same name. +use test::B2; //~ ERROR unused import: `test::B2` + +// Make sure this import is warned about when at least one of its imported names +// is unused +use test2::{foo, bar}; //~ ERROR unused import: `bar` + +mod test2 { + pub fn foo() {} + pub fn bar() {} +} + +mod test { + pub trait A { fn a(&self) {} } + pub trait B { fn b(&self) {} } + pub trait B2 { fn b(&self) {} } + pub struct C; + impl A for C {} + impl B for C {} +} + +mod foo { + pub struct Point{pub x: isize, pub y: isize} + pub struct Square{pub p: Point, pub h: usize, pub w: usize} +} + +mod bar { + // Don't ignore on 'pub use' because we're not sure if it's used or not + pub use std::cmp::PartialEq; + pub struct Square; + + pub mod c { + use foo::Point; + use foo::Square; //~ ERROR unused import: `foo::Square` + pub fn cc(_p: Point) -> super::Square { + fn f() -> super::Square { + super::Square + } + f() + } + } + + #[allow(unused_imports)] + mod foo { + use std::cmp::PartialEq; + } +} + +fn g() { + use self::g; //~ ERROR unused import: `self::g` + //~^ ERROR the item `g` is imported redundantly + fn f() { + self::g(); + } +} + +// cf. issue #35135. +#[allow(unused_variables)] +fn h() { + use test2::foo; //~ ERROR unused import: `test2::foo` + //~^ ERROR the item `foo` is imported redundantly + let foo = 0; +} + +fn main() { + cal(foo::Point{x:3, y:9}); + let mut a = 3; + let mut b = 4; + swap(&mut a, &mut b); + test::C.b(); + let _a = foo(); +} diff --git a/src/test/ui/lint/unused/lint-unused-imports.stderr b/src/test/ui/lint/unused/lint-unused-imports.stderr new file mode 100644 index 000000000..0574ca456 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-imports.stderr @@ -0,0 +1,78 @@ +error: unused import: `std::fmt::{}` + --> $DIR/lint-unused-imports.rs:8:5 + | +LL | use std::fmt::{}; + | ^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-unused-imports.rs:1:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: unused imports: `None`, `Some` + --> $DIR/lint-unused-imports.rs:12:27 + | +LL | use std::option::Option::{Some, None}; + | ^^^^ ^^^^ + +error: unused import: `test::A` + --> $DIR/lint-unused-imports.rs:15:5 + | +LL | use test::A; + | ^^^^^^^ + +error: unused import: `bar` + --> $DIR/lint-unused-imports.rs:24:18 + | +LL | use test2::{foo, bar}; + | ^^^ + +error: unused import: `foo::Square` + --> $DIR/lint-unused-imports.rs:52:13 + | +LL | use foo::Square; + | ^^^^^^^^^^^ + +error: the item `g` is imported redundantly + --> $DIR/lint-unused-imports.rs:68:9 + | +LL | / fn g() { +LL | | use self::g; + | | ^^^^^^^ +LL | | +LL | | fn f() { +LL | | self::g(); +LL | | } +LL | | } + | |_- the item `g` is already defined here + +error: unused import: `self::g` + --> $DIR/lint-unused-imports.rs:68:9 + | +LL | use self::g; + | ^^^^^^^ + +error: the item `foo` is imported redundantly + --> $DIR/lint-unused-imports.rs:78:9 + | +LL | use test2::{foo, bar}; + | --- the item `foo` is already imported here +... +LL | use test2::foo; + | ^^^^^^^^^^ + +error: unused import: `test2::foo` + --> $DIR/lint-unused-imports.rs:78:9 + | +LL | use test2::foo; + | ^^^^^^^^^^ + +error: unused import: `test::B2` + --> $DIR/lint-unused-imports.rs:20:5 + | +LL | use test::B2; + | ^^^^^^^^ + +error: aborting due to 10 previous errors + diff --git a/src/test/ui/lint/unused/lint-unused-mut-self.fixed b/src/test/ui/lint/unused/lint-unused-mut-self.fixed new file mode 100644 index 000000000..92ce10358 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-mut-self.fixed @@ -0,0 +1,14 @@ +// run-rustfix + +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![allow(dead_code)] +#![deny(unused_mut)] + +struct Foo; +impl Foo { + fn foo(self) {} //~ ERROR: variable does not need to be mutable + fn bar(self: Box<Foo>) {} //~ ERROR: variable does not need to be mutable +} + +fn main() {} diff --git a/src/test/ui/lint/unused/lint-unused-mut-self.rs b/src/test/ui/lint/unused/lint-unused-mut-self.rs new file mode 100644 index 000000000..70736ce21 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-mut-self.rs @@ -0,0 +1,14 @@ +// run-rustfix + +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![allow(dead_code)] +#![deny(unused_mut)] + +struct Foo; +impl Foo { + fn foo(mut self) {} //~ ERROR: variable does not need to be mutable + fn bar(mut self: Box<Foo>) {} //~ ERROR: variable does not need to be mutable +} + +fn main() {} diff --git a/src/test/ui/lint/unused/lint-unused-mut-self.stderr b/src/test/ui/lint/unused/lint-unused-mut-self.stderr new file mode 100644 index 000000000..01a524bd3 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-mut-self.stderr @@ -0,0 +1,24 @@ +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-self.rs:10:12 + | +LL | fn foo(mut self) {} + | ----^^^^ + | | + | help: remove this `mut` + | +note: the lint level is defined here + --> $DIR/lint-unused-mut-self.rs:6:9 + | +LL | #![deny(unused_mut)] + | ^^^^^^^^^^ + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-self.rs:11:12 + | +LL | fn bar(mut self: Box<Foo>) {} + | ----^^^^ + | | + | help: remove this `mut` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/unused/lint-unused-mut-variables.rs b/src/test/ui/lint/unused/lint-unused-mut-variables.rs new file mode 100644 index 000000000..67ec7facf --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-mut-variables.rs @@ -0,0 +1,207 @@ +// edition:2018 + +// Exercise the unused_mut attribute in some positive and negative cases + +#![warn(unused_mut)] +#![feature(async_closure, raw_ref_op)] + +async fn baz_async( + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, +) {} +fn baz( + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) +) {} + +struct RefStruct {} +impl RefStruct { + async fn baz_async( + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + ) {} + fn baz( + &self, + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} + +trait RefTrait { + fn baz( + &self, + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} +impl RefTrait for () { + fn baz( + &self, + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} + +fn main() { + let _ = async move | + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + | {}; + let _ = | + mut a: i32, + //~^ WARN: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + | {}; + + // negative cases + let mut a = 3; //~ WARN: variable does not need to be mutable + + let mut a = 2; //~ WARN: variable does not need to be mutable + + let mut b = 3; //~ WARN: variable does not need to be mutable + + let mut a = vec![3]; //~ WARN: variable does not need to be mutable + + let (mut a, b) = (1, 2); //~ WARN: variable does not need to be mutable + + let mut a; //~ WARN: variable does not need to be mutable + + a = 3; + + let mut b; //~ WARN: variable does not need to be mutable + + if true { + b = 3; + } else { + b = 4; + } + + match 30 { + mut x => {} //~ WARN: variable does not need to be mutable + + } + + match (30, 2) { + // FIXME: Here's a false positive, + // shouldn't be removed `mut` not to be bound with a different way. + (mut x, 1) | //~ WARN: variable does not need to be mutable + + (mut x, 2) | + (mut x, 3) => { + } + _ => {} + } + + let x = |mut y: isize| 10; //~ WARN: variable does not need to be mutable + + fn what(mut foo: isize) {} //~ WARN: variable does not need to be mutable + + + let mut a = &mut 5; //~ WARN: variable does not need to be mutable + + *a = 4; + + let mut a = 5; + let mut b = (&mut a,); //~ WARN: variable does not need to be mutable + *b.0 = 4; + + let mut x = &mut 1; //~ WARN: variable does not need to be mutable + + let mut f = || { + *x += 1; + }; + f(); + + fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { + &mut arg[..] //~^ WARN: variable does not need to be mutable + + } + + let mut v : &mut Vec<()> = &mut vec![]; //~ WARN: variable does not need to be mutable + + v.push(()); + + // positive cases + let mut a = 2; + a = 3; + let mut a = Vec::new(); + a.push(3); + let mut a = Vec::new(); + callback(|| { + a.push(3); + }); + let mut a = Vec::new(); + callback(|| { + callback(|| { + a.push(3); + }); + }); + let (mut a, b) = (1, 2); + a = 34; + + match 30 { + mut x => { + x = 21; + } + } + + match (30, 2) { + (mut x, 1) | + (mut x, 2) | + (mut x, 3) => { + x = 21 + } + _ => {} + } + + // Attribute should be respected on match arms + match 0 { + #[allow(unused_mut)] + mut x => { + let mut y = 1; + }, + } + + let x = |mut y: isize| y = 32; + fn nothing(mut foo: isize) { foo = 37; } + + // leading underscore should avoid the warning, just like the + // unused variable lint. + let mut _allowed = 1; + + let mut raw_address_of_mut = 1; // OK + let mut_ptr = &raw mut raw_address_of_mut; + + let mut raw_address_of_const = 1; //~ WARN: variable does not need to be mutable + let const_ptr = &raw const raw_address_of_const; +} + +fn callback<F>(f: F) where F: FnOnce() {} + +// make sure the lint attribute can be turned off +#[allow(unused_mut)] +fn foo(mut a: isize) { + let mut a = 3; + let mut b = vec![2]; +} + +// make sure the lint attribute can be turned off on let statements +#[deny(unused_mut)] +fn bar() { + #[allow(unused_mut)] + let mut a = 3; + let mut b = vec![2]; //~ ERROR: variable does not need to be mutable + +} diff --git a/src/test/ui/lint/unused/lint-unused-mut-variables.stderr b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr new file mode 100644 index 000000000..805ed2b40 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr @@ -0,0 +1,222 @@ +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:9:5 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + | +note: the lint level is defined here + --> $DIR/lint-unused-mut-variables.rs:5:9 + | +LL | #![warn(unused_mut)] + | ^^^^^^^^^^ + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:23:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:14:5 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:29:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:39:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:48:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:57:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:62:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:107:14 + | +LL | let x = |mut y: isize| 10; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:69:9 + | +LL | let mut a = 3; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:71:9 + | +LL | let mut a = 2; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:73:9 + | +LL | let mut b = 3; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:75:9 + | +LL | let mut a = vec![3]; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:77:10 + | +LL | let (mut a, b) = (1, 2); + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:79:9 + | +LL | let mut a; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:83:9 + | +LL | let mut b; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:92:9 + | +LL | mut x => {} + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:99:10 + | +LL | (mut x, 1) | + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:112:9 + | +LL | let mut a = &mut 5; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:117:9 + | +LL | let mut b = (&mut a,); + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:120:9 + | +LL | let mut x = &mut 1; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:132:9 + | +LL | let mut v : &mut Vec<()> = &mut vec![]; + | ----^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:187:9 + | +LL | let mut raw_address_of_const = 1; + | ----^^^^^^^^^^^^^^^^^^^^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:109:13 + | +LL | fn what(mut foo: isize) {} + | ----^^^ + | | + | help: remove this `mut` + +warning: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:127:20 + | +LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { + | ----^^^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:205:9 + | +LL | let mut b = vec![2]; + | ----^ + | | + | help: remove this `mut` + | +note: the lint level is defined here + --> $DIR/lint-unused-mut-variables.rs:201:8 + | +LL | #[deny(unused_mut)] + | ^^^^^^^^^^ + +error: aborting due to previous error; 25 warnings emitted + diff --git a/src/test/ui/lint/unused/lint-unused-variables.rs b/src/test/ui/lint/unused/lint-unused-variables.rs new file mode 100644 index 000000000..6850e9992 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-variables.rs @@ -0,0 +1,79 @@ +// compile-flags: --cfg something +// edition:2018 + +#![feature(async_closure)] +#![deny(unused_variables)] + +async fn foo_async( + a: i32, + //~^ ERROR unused variable: `a` + #[allow(unused_variables)] b: i32, +) {} +fn foo( + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` +) {} + +struct RefStruct {} +impl RefStruct { + async fn bar_async( + &self, + a: i32, + //~^ ERROR unused variable: `a` + #[allow(unused_variables)] b: i32, + ) {} + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} + fn issue_64682_associated_fn( + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} +} +trait RefTrait { + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} + fn issue_64682_associated_fn( + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} +} +impl RefTrait for RefStruct { + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} + fn issue_64682_associated_fn( + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} +} + +fn main() { + let _: fn(_, _) = foo; + let a = async move | + a: i32, + //~^ ERROR unused variable: `a` + #[allow(unused_variables)] b: i32, + | {}; + let b = | + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + | {}; + let _ = a(1, 2); + let _ = b(1, 2); +} diff --git a/src/test/ui/lint/unused/lint-unused-variables.stderr b/src/test/ui/lint/unused/lint-unused-variables.stderr new file mode 100644 index 000000000..d6e684e83 --- /dev/null +++ b/src/test/ui/lint/unused/lint-unused-variables.stderr @@ -0,0 +1,74 @@ +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:8:5 + | +LL | a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: the lint level is defined here + --> $DIR/lint-unused-variables.rs:5:9 + | +LL | #![deny(unused_variables)] + | ^^^^^^^^^^^^^^^^ + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:14:5 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:68:9 + | +LL | a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:74:9 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:42:9 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:47:9 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:22:9 + | +LL | a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:29:9 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:34:9 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:55:9 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:60:9 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: aborting due to 11 previous errors + diff --git a/src/test/ui/lint/unused/must-use-box-from-raw.rs b/src/test/ui/lint/unused/must-use-box-from-raw.rs new file mode 100644 index 000000000..9ea772689 --- /dev/null +++ b/src/test/ui/lint/unused/must-use-box-from-raw.rs @@ -0,0 +1,11 @@ +// #99269 + +// check-pass + +#![warn(unused_must_use)] + +unsafe fn free<T>(ptr: *mut T) { + Box::from_raw(ptr); //~ WARNING unused return value +} + +fn main() {} diff --git a/src/test/ui/lint/unused/must-use-box-from-raw.stderr b/src/test/ui/lint/unused/must-use-box-from-raw.stderr new file mode 100644 index 000000000..7769f09aa --- /dev/null +++ b/src/test/ui/lint/unused/must-use-box-from-raw.stderr @@ -0,0 +1,15 @@ +warning: unused return value of `Box::<T>::from_raw` that must be used + --> $DIR/must-use-box-from-raw.rs:8:5 + | +LL | Box::from_raw(ptr); + | ^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must-use-box-from-raw.rs:5:9 + | +LL | #![warn(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: call `drop(from_raw(ptr))` if you intend to drop the `Box` + +warning: 1 warning emitted + diff --git a/src/test/ui/lint/unused/must-use-ops.rs b/src/test/ui/lint/unused/must-use-ops.rs new file mode 100644 index 000000000..3e425727e --- /dev/null +++ b/src/test/ui/lint/unused/must-use-ops.rs @@ -0,0 +1,41 @@ +// Issue #50124 - Test warning for unused operator expressions + +// check-pass + +#![warn(unused_must_use)] + +fn main() { + let val = 1; + let val_pointer = &val; + +// Comparison Operators + val == 1; //~ WARNING unused comparison + val < 1; //~ WARNING unused comparison + val <= 1; //~ WARNING unused comparison + val != 1; //~ WARNING unused comparison + val >= 1; //~ WARNING unused comparison + val > 1; //~ WARNING unused comparison + +// Arithmetic Operators + val + 2; //~ WARNING unused arithmetic operation + val - 2; //~ WARNING unused arithmetic operation + val / 2; //~ WARNING unused arithmetic operation + val * 2; //~ WARNING unused arithmetic operation + val % 2; //~ WARNING unused arithmetic operation + +// Logical Operators + true && true; //~ WARNING unused logical operation + false || true; //~ WARNING unused logical operation + +// Bitwise Operators + 5 ^ val; //~ WARNING unused bitwise operation + 5 & val; //~ WARNING unused bitwise operation + 5 | val; //~ WARNING unused bitwise operation + 5 << val; //~ WARNING unused bitwise operation + 5 >> val; //~ WARNING unused bitwise operation + +// Unary Operators + !val; //~ WARNING unused unary operation + -val; //~ WARNING unused unary operation + *val_pointer; //~ WARNING unused unary operation +} diff --git a/src/test/ui/lint/unused/must-use-ops.stderr b/src/test/ui/lint/unused/must-use-ops.stderr new file mode 100644 index 000000000..b248dd0fe --- /dev/null +++ b/src/test/ui/lint/unused/must-use-ops.stderr @@ -0,0 +1,238 @@ +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:12:5 + | +LL | val == 1; + | ^^^^^^^^ the comparison produces a value + | +note: the lint level is defined here + --> $DIR/must-use-ops.rs:5:9 + | +LL | #![warn(unused_must_use)] + | ^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val == 1; + | +++++++ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:13:5 + | +LL | val < 1; + | ^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val < 1; + | +++++++ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:14:5 + | +LL | val <= 1; + | ^^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val <= 1; + | +++++++ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:15:5 + | +LL | val != 1; + | ^^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val != 1; + | +++++++ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:16:5 + | +LL | val >= 1; + | ^^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val >= 1; + | +++++++ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:17:5 + | +LL | val > 1; + | ^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val > 1; + | +++++++ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:20:5 + | +LL | val + 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val + 2; + | +++++++ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:21:5 + | +LL | val - 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val - 2; + | +++++++ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:22:5 + | +LL | val / 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val / 2; + | +++++++ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:23:5 + | +LL | val * 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val * 2; + | +++++++ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:24:5 + | +LL | val % 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val % 2; + | +++++++ + +warning: unused logical operation that must be used + --> $DIR/must-use-ops.rs:27:5 + | +LL | true && true; + | ^^^^^^^^^^^^ the logical operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = true && true; + | +++++++ + +warning: unused logical operation that must be used + --> $DIR/must-use-ops.rs:28:5 + | +LL | false || true; + | ^^^^^^^^^^^^^ the logical operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = false || true; + | +++++++ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:31:5 + | +LL | 5 ^ val; + | ^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 ^ val; + | +++++++ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:32:5 + | +LL | 5 & val; + | ^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 & val; + | +++++++ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:33:5 + | +LL | 5 | val; + | ^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 | val; + | +++++++ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:34:5 + | +LL | 5 << val; + | ^^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 << val; + | +++++++ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:35:5 + | +LL | 5 >> val; + | ^^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 >> val; + | +++++++ + +warning: unused unary operation that must be used + --> $DIR/must-use-ops.rs:38:5 + | +LL | !val; + | ^^^^ the unary operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = !val; + | +++++++ + +warning: unused unary operation that must be used + --> $DIR/must-use-ops.rs:39:5 + | +LL | -val; + | ^^^^ the unary operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = -val; + | +++++++ + +warning: unused unary operation that must be used + --> $DIR/must-use-ops.rs:40:5 + | +LL | *val_pointer; + | ^^^^^^^^^^^^ the unary operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = *val_pointer; + | +++++++ + +warning: 21 warnings emitted + diff --git a/src/test/ui/lint/unused/must_use-array.rs b/src/test/ui/lint/unused/must_use-array.rs new file mode 100644 index 000000000..97825dd2f --- /dev/null +++ b/src/test/ui/lint/unused/must_use-array.rs @@ -0,0 +1,47 @@ +#![deny(unused_must_use)] + +#[must_use] +struct S; + +struct A; + +#[must_use] +trait T {} + +impl T for A {} + +fn empty() -> [S; 0] { + [] +} + +fn singleton() -> [S; 1] { + [S] +} + +fn many() -> [S; 4] { + [S, S, S, S] +} + +fn array_of_impl_trait() -> [impl T; 2] { + [A, A] +} + +fn impl_array() -> [(u8, Box<dyn T>); 2] { + [(0, Box::new(A)), (0, Box::new(A))] +} + +fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] { + [[[S], [S]]] +} + +fn main() { + empty(); // ok + singleton(); //~ ERROR unused array of `S` that must be used + many(); //~ ERROR unused array of `S` that must be used + ([S], 0, ()); //~ ERROR unused array of `S` in tuple element 0 that must be used + array_of_impl_trait(); //~ ERROR unused array of implementers of `T` that must be used + impl_array(); + //~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used + array_of_arrays_of_arrays(); + //~^ ERROR unused array of arrays of arrays of `S` that must be used +} diff --git a/src/test/ui/lint/unused/must_use-array.stderr b/src/test/ui/lint/unused/must_use-array.stderr new file mode 100644 index 000000000..45a5317fc --- /dev/null +++ b/src/test/ui/lint/unused/must_use-array.stderr @@ -0,0 +1,44 @@ +error: unused array of `S` that must be used + --> $DIR/must_use-array.rs:39:5 + | +LL | singleton(); + | ^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must_use-array.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: unused array of `S` that must be used + --> $DIR/must_use-array.rs:40:5 + | +LL | many(); + | ^^^^^^^ + +error: unused array of `S` in tuple element 0 that must be used + --> $DIR/must_use-array.rs:41:6 + | +LL | ([S], 0, ()); + | ^^^ + +error: unused array of implementers of `T` that must be used + --> $DIR/must_use-array.rs:42:5 + | +LL | array_of_impl_trait(); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unused array of boxed `T` trait objects in tuple element 1 that must be used + --> $DIR/must_use-array.rs:43:5 + | +LL | impl_array(); + | ^^^^^^^^^^^^ + +error: unused array of arrays of arrays of `S` that must be used + --> $DIR/must_use-array.rs:45:5 + | +LL | array_of_arrays_of_arrays(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/lint/unused/must_use-in-stdlib-traits.rs b/src/test/ui/lint/unused/must_use-in-stdlib-traits.rs new file mode 100644 index 000000000..70dddf61f --- /dev/null +++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.rs @@ -0,0 +1,47 @@ +#![deny(unused_must_use)] +#![feature(arbitrary_self_types)] + +use std::iter::Iterator; +use std::future::Future; + +use std::task::{Context, Poll}; +use std::pin::Pin; +use std::unimplemented; + +struct MyFuture; + +impl Future for MyFuture { + type Output = u32; + + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<u32> { + Poll::Pending + } +} + +fn iterator() -> impl Iterator { + std::iter::empty::<u32>() +} + +fn future() -> impl Future { + MyFuture +} + +fn square_fn_once() -> impl FnOnce(u32) -> u32 { + |x| x * x +} + +fn square_fn_mut() -> impl FnMut(u32) -> u32 { + |x| x * x +} + +fn square_fn() -> impl Fn(u32) -> u32 { + |x| x * x +} + +fn main() { + iterator(); //~ ERROR unused implementer of `Iterator` that must be used + future(); //~ ERROR unused implementer of `Future` that must be used + square_fn_once(); //~ ERROR unused implementer of `FnOnce` that must be used + square_fn_mut(); //~ ERROR unused implementer of `FnMut` that must be used + square_fn(); //~ ERROR unused implementer of `Fn` that must be used +} diff --git a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr new file mode 100644 index 000000000..76978d29d --- /dev/null +++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr @@ -0,0 +1,47 @@ +error: unused implementer of `Iterator` that must be used + --> $DIR/must_use-in-stdlib-traits.rs:42:4 + | +LL | iterator(); + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must_use-in-stdlib-traits.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: iterators are lazy and do nothing unless consumed + +error: unused implementer of `Future` that must be used + --> $DIR/must_use-in-stdlib-traits.rs:43:4 + | +LL | future(); + | ^^^^^^^^^ + | + = note: futures do nothing unless you `.await` or poll them + +error: unused implementer of `FnOnce` that must be used + --> $DIR/must_use-in-stdlib-traits.rs:44:4 + | +LL | square_fn_once(); + | ^^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused implementer of `FnMut` that must be used + --> $DIR/must_use-in-stdlib-traits.rs:45:4 + | +LL | square_fn_mut(); + | ^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused implementer of `Fn` that must be used + --> $DIR/must_use-in-stdlib-traits.rs:46:4 + | +LL | square_fn(); + | ^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/lint/unused/must_use-trait.rs b/src/test/ui/lint/unused/must_use-trait.rs new file mode 100644 index 000000000..0aa751443 --- /dev/null +++ b/src/test/ui/lint/unused/must_use-trait.rs @@ -0,0 +1,39 @@ +#![deny(unused_must_use)] + +#[must_use] +trait Critical {} + +trait NotSoCritical {} + +trait DecidedlyUnimportant {} + +struct Anon; + +impl Critical for Anon {} +impl NotSoCritical for Anon {} +impl DecidedlyUnimportant for Anon {} + +fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant { + Anon {} +} + +fn get_boxed_critical() -> Box<dyn Critical> { + Box::new(Anon {}) +} + +fn get_nested_boxed_critical() -> Box<Box<dyn Critical>> { + Box::new(Box::new(Anon {})) +} + +fn get_critical_tuple() -> (u32, Box<dyn Critical>, impl Critical, ()) { + (0, get_boxed_critical(), get_critical(), ()) +} + +fn main() { + get_critical(); //~ ERROR unused implementer of `Critical` that must be used + get_boxed_critical(); //~ ERROR unused boxed `Critical` trait object that must be used + get_nested_boxed_critical(); + //~^ ERROR unused boxed boxed `Critical` trait object that must be used + get_critical_tuple(); //~ ERROR unused boxed `Critical` trait object in tuple element 1 + //~^ ERROR unused implementer of `Critical` in tuple element 2 +} diff --git a/src/test/ui/lint/unused/must_use-trait.stderr b/src/test/ui/lint/unused/must_use-trait.stderr new file mode 100644 index 000000000..a42eb8841 --- /dev/null +++ b/src/test/ui/lint/unused/must_use-trait.stderr @@ -0,0 +1,38 @@ +error: unused implementer of `Critical` that must be used + --> $DIR/must_use-trait.rs:33:5 + | +LL | get_critical(); + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must_use-trait.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: unused boxed `Critical` trait object that must be used + --> $DIR/must_use-trait.rs:34:5 + | +LL | get_boxed_critical(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: unused boxed boxed `Critical` trait object that must be used + --> $DIR/must_use-trait.rs:35:5 + | +LL | get_nested_boxed_critical(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unused boxed `Critical` trait object in tuple element 1 that must be used + --> $DIR/must_use-trait.rs:37:5 + | +LL | get_critical_tuple(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: unused implementer of `Critical` in tuple element 2 that must be used + --> $DIR/must_use-trait.rs:37:5 + | +LL | get_critical_tuple(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/lint/unused/must_use-tuple.rs b/src/test/ui/lint/unused/must_use-tuple.rs new file mode 100644 index 000000000..0f0aa2025 --- /dev/null +++ b/src/test/ui/lint/unused/must_use-tuple.rs @@ -0,0 +1,17 @@ +#![deny(unused_must_use)] + +fn foo() -> (Result<(), ()>, ()) { + (Ok::<(), ()>(()), ()) +} + +fn main() { + (Ok::<(), ()>(()),); //~ ERROR unused `Result` + + (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); + //~^ ERROR unused `Result` + //~^^ ERROR unused `Result` + + foo(); //~ ERROR unused `Result` + + ((Err::<(), ()>(()), ()), ()); //~ ERROR unused `Result` +} diff --git a/src/test/ui/lint/unused/must_use-tuple.stderr b/src/test/ui/lint/unused/must_use-tuple.stderr new file mode 100644 index 000000000..e5709a5f0 --- /dev/null +++ b/src/test/ui/lint/unused/must_use-tuple.stderr @@ -0,0 +1,47 @@ +error: unused `Result` in tuple element 0 that must be used + --> $DIR/must_use-tuple.rs:8:6 + | +LL | (Ok::<(), ()>(()),); + | ^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must_use-tuple.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: this `Result` may be an `Err` variant, which should be handled + +error: unused `Result` in tuple element 0 that must be used + --> $DIR/must_use-tuple.rs:10:6 + | +LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); + | ^^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled + +error: unused `Result` in tuple element 2 that must be used + --> $DIR/must_use-tuple.rs:10:27 + | +LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); + | ^^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled + +error: unused `Result` in tuple element 0 that must be used + --> $DIR/must_use-tuple.rs:14:5 + | +LL | foo(); + | ^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled + +error: unused `Result` in tuple element 0 that must be used + --> $DIR/must_use-tuple.rs:16:7 + | +LL | ((Err::<(), ()>(()), ()), ()); + | ^^^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/lint/unused/must_use-unit.rs b/src/test/ui/lint/unused/must_use-unit.rs new file mode 100644 index 000000000..4dd4798ab --- /dev/null +++ b/src/test/ui/lint/unused/must_use-unit.rs @@ -0,0 +1,16 @@ +#![feature(never_type)] +#![deny(unused_must_use)] + +#[must_use] +fn foo() {} + +#[must_use] +fn bar() -> ! { + unimplemented!() +} + +fn main() { + foo(); //~ unused return value of `foo` + + bar(); //~ unused return value of `bar` +} diff --git a/src/test/ui/lint/unused/must_use-unit.stderr b/src/test/ui/lint/unused/must_use-unit.stderr new file mode 100644 index 000000000..7f25a1935 --- /dev/null +++ b/src/test/ui/lint/unused/must_use-unit.stderr @@ -0,0 +1,20 @@ +error: unused return value of `foo` that must be used + --> $DIR/must_use-unit.rs:13:5 + | +LL | foo(); + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/must_use-unit.rs:2:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: unused return value of `bar` that must be used + --> $DIR/must_use-unit.rs:15:5 + | +LL | bar(); + | ^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/unused/no-unused-parens-return-block.rs b/src/test/ui/lint/unused/no-unused-parens-return-block.rs new file mode 100644 index 000000000..37dc519a2 --- /dev/null +++ b/src/test/ui/lint/unused/no-unused-parens-return-block.rs @@ -0,0 +1,9 @@ +// run-pass + +#![deny(unused_parens)] +#![allow(unreachable_code)] + +fn main() { + match (return) {} // ok + if (return) {} // ok +} diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs new file mode 100644 index 000000000..7d17af115 --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.rs @@ -0,0 +1,43 @@ +// edition:2018 +// run-pass +#![allow(dead_code)] + +#[must_use] +//~^ WARNING `must_use` +async fn test() -> i32 { + 1 +} + + +struct Wowee {} + +impl Wowee { + #[must_use] + //~^ WARNING `must_use` + async fn test_method() -> i32 { + 1 + } +} + +/* FIXME(guswynn) update this test when async-fn-in-traits works +trait Doer { + #[must_use] + async fn test_trait_method() -> i32; + WARNING must_use + async fn test_other_trait() -> i32; +} + +impl Doer for Wowee { + async fn test_trait_method() -> i32 { + 1 + } + #[must_use] + async fn test_other_trait() -> i32 { + WARNING must_use + 1 + } +} +*/ + +fn main() { +} diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr new file mode 100644 index 000000000..6bbc9e2bf --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -0,0 +1,26 @@ +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within + --> $DIR/unused-async.rs:5:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test() -> i32 { +LL | | 1 +LL | | } + | |_- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + | + = note: `#[warn(unused_attributes)]` on by default + +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within + --> $DIR/unused-async.rs:15:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test_method() -> i32 { +LL | | 1 +LL | | } + | |_____- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + +warning: 2 warnings emitted + diff --git a/src/test/ui/lint/unused/unused-attr-duplicate.rs b/src/test/ui/lint/unused/unused-attr-duplicate.rs new file mode 100644 index 000000000..692617eac --- /dev/null +++ b/src/test/ui/lint/unused/unused-attr-duplicate.rs @@ -0,0 +1,105 @@ +// Tests for repeating attribute warnings. +// aux-build:lint_unused_extern_crate.rs +// compile-flags:--test +// Not tested due to extra requirements: +// - panic_handler: needs extra setup +// - target_feature: platform-specific +// - link_section: platform-specific +// - proc_macro, proc_macro_derive, proc_macro_attribute: needs to be a +// proc-macro, and have special handling for mixing. +// - unstable attributes (not going to bother) +// - no_main: extra setup +#![deny(unused_attributes)] +#![crate_name = "unused_attr_duplicate"] +#![crate_name = "unused_attr_duplicate2"] //~ ERROR unused attribute +//~^ WARN this was previously accepted +#![recursion_limit = "128"] +#![recursion_limit = "256"] //~ ERROR unused attribute +//~^ WARN this was previously accepted +#![type_length_limit = "1048576"] +#![type_length_limit = "1"] //~ ERROR unused attribute +//~^ WARN this was previously accepted +#![no_std] +#![no_std] //~ ERROR unused attribute +#![no_implicit_prelude] +#![no_implicit_prelude] //~ ERROR unused attribute +#![windows_subsystem = "console"] +#![windows_subsystem = "windows"] //~ ERROR unused attribute +//~^ WARN this was previously accepted +#![no_builtins] +#![no_builtins] //~ ERROR unused attribute + +#[no_link] +#[no_link] //~ ERROR unused attribute +extern crate lint_unused_extern_crate; + +#[macro_use] +#[macro_use] //~ ERROR unused attribute +pub mod m { + #[macro_export] + #[macro_export] //~ ERROR unused attribute + macro_rules! foo { + () => {}; + } +} + +#[path = "auxiliary/lint_unused_extern_crate.rs"] +#[path = "bar.rs"] //~ ERROR unused attribute +//~^ WARN this was previously accepted +pub mod from_path; + +#[test] +#[ignore] +#[ignore = "some text"] //~ ERROR unused attribute +#[should_panic] +#[should_panic(expected = "values don't match")] //~ ERROR unused attribute +//~^ WARN this was previously accepted +fn t1() {} + +#[must_use] +#[must_use = "some message"] //~ ERROR unused attribute +//~^ WARN this was previously accepted +// No warnings for #[repr], would require more logic. +#[repr(C)] +#[repr(C)] +#[non_exhaustive] +#[non_exhaustive] //~ ERROR unused attribute +pub struct X; + +#[automatically_derived] +#[automatically_derived] //~ ERROR unused attribute +impl X {} + +#[inline(always)] +#[inline(never)] //~ ERROR unused attribute +//~^ WARN this was previously accepted +#[cold] +#[cold] //~ ERROR unused attribute +#[track_caller] +#[track_caller] //~ ERROR unused attribute +pub fn xyz() {} + +// No warnings for #[link], would require more logic. +#[link(name = "rust_test_helpers", kind = "static")] +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + #[link_name = "this_does_not_exist"] //~ ERROR unused attribute + //~^ WARN this was previously accepted + #[link_name = "rust_dbg_extern_identity_u32"] + pub fn name_in_rust(v: u32) -> u32; +} + +#[export_name = "exported_symbol_name"] //~ ERROR unused attribute +//~^ WARN this was previously accepted +#[export_name = "exported_symbol_name2"] +pub fn export_test() {} + +#[no_mangle] +#[no_mangle] //~ ERROR unused attribute +pub fn no_mangle_test() {} + +#[used] +#[used] //~ ERROR unused attribute +static FOO: u32 = 0; + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-attr-duplicate.stderr b/src/test/ui/lint/unused/unused-attr-duplicate.stderr new file mode 100644 index 000000000..f592323b5 --- /dev/null +++ b/src/test/ui/lint/unused/unused-attr-duplicate.stderr @@ -0,0 +1,293 @@ +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:33:1 + | +LL | #[no_link] + | ^^^^^^^^^^ help: remove this attribute + | +note: the lint level is defined here + --> $DIR/unused-attr-duplicate.rs:12:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:32:1 + | +LL | #[no_link] + | ^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:37:1 + | +LL | #[macro_use] + | ^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:36:1 + | +LL | #[macro_use] + | ^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:47:1 + | +LL | #[path = "bar.rs"] + | ^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:46:1 + | +LL | #[path = "auxiliary/lint_unused_extern_crate.rs"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:53:1 + | +LL | #[ignore = "some text"] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:52:1 + | +LL | #[ignore] + | ^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:55:1 + | +LL | #[should_panic(expected = "values don't match")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:54:1 + | +LL | #[should_panic] + | ^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:60:1 + | +LL | #[must_use = "some message"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:59:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:66:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:65:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:70:1 + | +LL | #[automatically_derived] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:69:1 + | +LL | #[automatically_derived] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:74:1 + | +LL | #[inline(never)] + | ^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:73:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:77:1 + | +LL | #[cold] + | ^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:76:1 + | +LL | #[cold] + | ^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:79:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:78:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:92:1 + | +LL | #[export_name = "exported_symbol_name"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:94:1 + | +LL | #[export_name = "exported_symbol_name2"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:98:1 + | +LL | #[no_mangle] + | ^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:97:1 + | +LL | #[no_mangle] + | ^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:102:1 + | +LL | #[used] + | ^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:101:1 + | +LL | #[used] + | ^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:86:5 + | +LL | #[link_name = "this_does_not_exist"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:88:5 + | +LL | #[link_name = "rust_dbg_extern_identity_u32"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:14:1 + | +LL | #![crate_name = "unused_attr_duplicate2"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:13:1 + | +LL | #![crate_name = "unused_attr_duplicate"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:17:1 + | +LL | #![recursion_limit = "256"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:16:1 + | +LL | #![recursion_limit = "128"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:20:1 + | +LL | #![type_length_limit = "1"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:19:1 + | +LL | #![type_length_limit = "1048576"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:23:1 + | +LL | #![no_std] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:22:1 + | +LL | #![no_std] + | ^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:25:1 + | +LL | #![no_implicit_prelude] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:24:1 + | +LL | #![no_implicit_prelude] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:27:1 + | +LL | #![windows_subsystem = "windows"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:26:1 + | +LL | #![windows_subsystem = "console"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:30:1 + | +LL | #![no_builtins] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:29:1 + | +LL | #![no_builtins] + | ^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:40:5 + | +LL | #[macro_export] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:39:5 + | +LL | #[macro_export] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 23 previous errors + diff --git a/src/test/ui/lint/unused/unused-attr-macro-rules.rs b/src/test/ui/lint/unused/unused-attr-macro-rules.rs new file mode 100644 index 000000000..c0fc280ab --- /dev/null +++ b/src/test/ui/lint/unused/unused-attr-macro-rules.rs @@ -0,0 +1,33 @@ +#![deny(unused_attributes)] +// Unused attributes on macro_rules requires special handling since the +// macro_rules definition does not survive towards HIR. + +// A sample of various built-in attributes. +#[macro_export] +#[macro_use] //~ ERROR `#[macro_use]` only has an effect +#[path="foo"] //~ ERROR #[path]` only has an effect +#[recursion_limit="1"] //~ ERROR crate-level attribute should be an inner attribute +macro_rules! foo { + () => {}; +} + +// The following should not warn about unused attributes. +#[allow(unused)] +macro_rules! foo2 { + () => {}; +} + +#[cfg(FALSE)] +macro_rules! foo { + () => {}; +} + +/// Some docs +#[deprecated] +#[doc = "more docs"] +#[macro_export] +macro_rules! bar { + () => {}; +} + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-attr-macro-rules.stderr b/src/test/ui/lint/unused/unused-attr-macro-rules.stderr new file mode 100644 index 000000000..e3ca90d9a --- /dev/null +++ b/src/test/ui/lint/unused/unused-attr-macro-rules.stderr @@ -0,0 +1,26 @@ +error: `#[macro_use]` only has an effect on `extern crate` and modules + --> $DIR/unused-attr-macro-rules.rs:7:1 + | +LL | #[macro_use] + | ^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-attr-macro-rules.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: `#[path]` only has an effect on modules + --> $DIR/unused-attr-macro-rules.rs:8:1 + | +LL | #[path="foo"] + | ^^^^^^^^^^^^^ + +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/unused-attr-macro-rules.rs:9:1 + | +LL | #[recursion_limit="1"] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/lint/unused/unused-closure.rs b/src/test/ui/lint/unused/unused-closure.rs new file mode 100644 index 000000000..c96c90731 --- /dev/null +++ b/src/test/ui/lint/unused/unused-closure.rs @@ -0,0 +1,35 @@ +// Test that closures and generators are "must use" types. +// edition:2018 + +#![feature(async_closure)] +#![feature(generators)] +#![deny(unused_must_use)] + +fn unused() { + || { //~ ERROR unused closure that must be used + println!("Hello!"); + }; + + async {}; //~ ERROR unused implementer of `Future` that must be used + || async {}; //~ ERROR unused closure that must be used + async || {}; //~ ERROR unused closure that must be used + + + [Box::new([|| {}; 10]); 1]; //~ ERROR unused array of boxed arrays of closures that must be used + + vec![|| "a"].pop().unwrap(); //~ ERROR unused closure that must be used + + let b = false; + || true; //~ ERROR unused closure that must be used + println!("{}", b); +} + +fn ignored() { + let _ = || {}; + let _ = || yield 42; +} + +fn main() { + unused(); + ignored(); +} diff --git a/src/test/ui/lint/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr new file mode 100644 index 000000000..265d3e8e0 --- /dev/null +++ b/src/test/ui/lint/unused/unused-closure.stderr @@ -0,0 +1,65 @@ +error: unused closure that must be used + --> $DIR/unused-closure.rs:9:5 + | +LL | / || { +LL | | println!("Hello!"); +LL | | }; + | |______^ + | +note: the lint level is defined here + --> $DIR/unused-closure.rs:6:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: closures are lazy and do nothing unless called + +error: unused implementer of `Future` that must be used + --> $DIR/unused-closure.rs:13:5 + | +LL | async {}; + | ^^^^^^^^^ + | + = note: futures do nothing unless you `.await` or poll them + +error: unused closure that must be used + --> $DIR/unused-closure.rs:14:5 + | +LL | || async {}; + | ^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused closure that must be used + --> $DIR/unused-closure.rs:15:5 + | +LL | async || {}; + | ^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused array of boxed arrays of closures that must be used + --> $DIR/unused-closure.rs:18:5 + | +LL | [Box::new([|| {}; 10]); 1]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused closure that must be used + --> $DIR/unused-closure.rs:20:5 + | +LL | vec![|| "a"].pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused closure that must be used + --> $DIR/unused-closure.rs:23:9 + | +LL | || true; + | ^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs new file mode 100644 index 000000000..54d86c31f --- /dev/null +++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs @@ -0,0 +1,46 @@ +#![deny(unused_doc_comments)] + +fn doc_comment_on_match_arms(num: u8) -> bool { + match num { + 3 => true, + /// useless doc comment + //~^ ERROR: unused doc comment + _ => false, + } +} + +fn doc_comment_between_if_else(num: u8) -> bool { + if num == 3 { + true //~ ERROR: mismatched types + } + /// useless doc comment + else { //~ ERROR: expected expression, found keyword `else` + false + } +} + +fn doc_comment_on_expr(num: u8) -> bool { + /// useless doc comment + //~^ ERROR: attributes on expressions are experimental + //~| ERROR: unused doc comment + num == 3 +} + +fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {} +//~^ ERROR: unused doc comment + +fn doc_comment_on_block() { + /// unused doc comment + //~^ ERROR: unused doc comment + { + let x = 12; + } +} + +/// unused doc comment +//~^ ERROR: unused doc comment +extern "C" { + fn foo(); +} + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr new file mode 100644 index 000000000..1a022c309 --- /dev/null +++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr @@ -0,0 +1,95 @@ +error: expected expression, found keyword `else` + --> $DIR/unused-doc-comments-edge-cases.rs:17:5 + | +LL | else { + | ^^^^ expected expression + +error[E0658]: attributes on expressions are experimental + --> $DIR/unused-doc-comments-edge-cases.rs:23:5 + | +LL | /// useless doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + = help: `///` is for documentation comments. For a plain comment, use `//`. + +error: unused doc comment + --> $DIR/unused-doc-comments-edge-cases.rs:6:9 + | +LL | /// useless doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | _ => false, + | ---------- rustdoc does not generate documentation for match arms + | +note: the lint level is defined here + --> $DIR/unused-doc-comments-edge-cases.rs:1:9 + | +LL | #![deny(unused_doc_comments)] + | ^^^^^^^^^^^^^^^^^^^ + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/unused-doc-comments-edge-cases.rs:23:5 + | +LL | /// useless doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | num == 3 + | --- rustdoc does not generate documentation for expressions + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/unused-doc-comments-edge-cases.rs:29:27 + | +LL | fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {} + | ^^^^^^^^^^^^ - rustdoc does not generate documentation for generic parameters + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/unused-doc-comments-edge-cases.rs:33:5 + | +LL | /// unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / { +LL | | let x = 12; +LL | | } + | |_____- rustdoc does not generate documentation for expressions + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/unused-doc-comments-edge-cases.rs:40:1 + | +LL | /// unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / extern "C" { +LL | | fn foo(); +LL | | } + | |_- rustdoc does not generate documentation for extern blocks + | + = help: use `//` for a plain comment + +error[E0308]: mismatched types + --> $DIR/unused-doc-comments-edge-cases.rs:14:9 + | +LL | / if num == 3 { +LL | | true + | | ^^^^ expected `()`, found `bool` +LL | | } + | |_____- expected this to be `()` + | +help: you might have meant to return this value + | +LL | return true; + | ++++++ + + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/lint/unused/unused-doc-comments-for-macros.rs b/src/test/ui/lint/unused/unused-doc-comments-for-macros.rs new file mode 100644 index 000000000..05828ebb2 --- /dev/null +++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.rs @@ -0,0 +1,17 @@ +#![deny(unused_doc_comments)] +#![feature(rustc_attrs)] + +macro_rules! foo { () => {}; } + +fn main() { + /// line1 //~ ERROR: unused doc comment + /// line2 + /// line3 + foo!(); + + // Ensure we still detect another doc-comment block. + /// line1 //~ ERROR: unused doc comment + /// line2 + /// line3 + foo!(); +} diff --git a/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr new file mode 100644 index 000000000..f4f5bb71e --- /dev/null +++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr @@ -0,0 +1,31 @@ +error: unused doc comment + --> $DIR/unused-doc-comments-for-macros.rs:7:5 + | +LL | / /// line1 +LL | | /// line2 +LL | | /// line3 + | |_____--------^ + | | + | rustdoc does not generate documentation for macro invocations + | +note: the lint level is defined here + --> $DIR/unused-doc-comments-for-macros.rs:1:9 + | +LL | #![deny(unused_doc_comments)] + | ^^^^^^^^^^^^^^^^^^^ + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion + +error: unused doc comment + --> $DIR/unused-doc-comments-for-macros.rs:13:5 + | +LL | / /// line1 +LL | | /// line2 +LL | | /// line3 + | |_____--------^ + | | + | rustdoc does not generate documentation for macro invocations + | + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/unused/unused-macro-rules-compile-error.rs b/src/test/ui/lint/unused/unused-macro-rules-compile-error.rs new file mode 100644 index 000000000..4d51db89b --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules-compile-error.rs @@ -0,0 +1,27 @@ +#![deny(unused_macro_rules)] +// To make sure we are not hitting this +#![deny(unused_macros)] + +macro_rules! num { + (one) => { 1 }; + // Most simple (and common) case + (two) => { compile_error!("foo"); }; + // Some nested use + (two_) => { foo(compile_error!("foo")); }; + (three) => { 3 }; + (four) => { 4 }; //~ ERROR: rule of macro +} +const _NUM: u8 = num!(one) + num!(three); + +// compile_error not used as a macro invocation +macro_rules! num2 { + (one) => { 1 }; + // Only identifier present + (two) => { fn compile_error() {} }; //~ ERROR: rule of macro + // Only identifier and bang present + (two_) => { compile_error! }; //~ ERROR: rule of macro + (three) => { 3 }; +} +const _NUM2: u8 = num2!(one) + num2!(three); + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-macro-rules-compile-error.stderr b/src/test/ui/lint/unused/unused-macro-rules-compile-error.stderr new file mode 100644 index 000000000..76af8c967 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules-compile-error.stderr @@ -0,0 +1,26 @@ +error: 5th rule of macro `num` is never used + --> $DIR/unused-macro-rules-compile-error.rs:12:5 + | +LL | (four) => { 4 }; + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macro-rules-compile-error.rs:1:9 + | +LL | #![deny(unused_macro_rules)] + | ^^^^^^^^^^^^^^^^^^ + +error: 3rd rule of macro `num2` is never used + --> $DIR/unused-macro-rules-compile-error.rs:22:5 + | +LL | (two_) => { compile_error! }; + | ^^^^^^ + +error: 2nd rule of macro `num2` is never used + --> $DIR/unused-macro-rules-compile-error.rs:20:5 + | +LL | (two) => { fn compile_error() {} }; + | ^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/lint/unused/unused-macro-rules-decl.rs b/src/test/ui/lint/unused/unused-macro-rules-decl.rs new file mode 100644 index 000000000..537c84940 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules-decl.rs @@ -0,0 +1,49 @@ +#![feature(decl_macro)] +#![deny(unused_macro_rules)] +// To make sure we are not hitting this +#![deny(unused_macros)] + +// Most simple case +macro num { + (one) => { 1 }, + (two) => { 2 }, //~ ERROR: 2nd rule of macro + (three) => { 3 }, + (four) => { 4 }, //~ ERROR: 4th rule of macro +} +const _NUM: u8 = num!(one) + num!(three); + +// Check that allowing the lint works +#[allow(unused_macro_rules)] +macro num_allowed { + (one) => { 1 }, + (two) => { 2 }, + (three) => { 3 }, + (four) => { 4 }, +} +const _NUM_ALLOWED: u8 = num_allowed!(one) + num_allowed!(three); + +// Check that macro calls inside the macro trigger as usage +macro num_rec { + (one) => { 1 }, + (two) => { + num_rec!(one) + num_rec!(one) + }, + (three) => { //~ ERROR: 3rd rule of macro + num_rec!(one) + num_rec!(two) + }, + (four) => { + num_rec!(two) + num_rec!(two) + }, +} +const _NUM_RECURSIVE: u8 = num_rec!(four); + +// No error if the macro is public +pub macro num_public { + (one) => { 1 }, + (two) => { 2 }, + (three) => { 3 }, + (four) => { 4 }, +} +const _NUM_PUBLIC: u8 = num_public!(one) + num_public!(three); + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-macro-rules-decl.stderr b/src/test/ui/lint/unused/unused-macro-rules-decl.stderr new file mode 100644 index 000000000..4d9b22fed --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules-decl.stderr @@ -0,0 +1,26 @@ +error: 4th rule of macro `num` is never used + --> $DIR/unused-macro-rules-decl.rs:11:5 + | +LL | (four) => { 4 }, + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macro-rules-decl.rs:2:9 + | +LL | #![deny(unused_macro_rules)] + | ^^^^^^^^^^^^^^^^^^ + +error: 2nd rule of macro `num` is never used + --> $DIR/unused-macro-rules-decl.rs:9:5 + | +LL | (two) => { 2 }, + | ^^^^^ + +error: 3rd rule of macro `num_rec` is never used + --> $DIR/unused-macro-rules-decl.rs:31:5 + | +LL | (three) => { + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/lint/unused/unused-macro-rules-malformed-rule.rs b/src/test/ui/lint/unused/unused-macro-rules-malformed-rule.rs new file mode 100644 index 000000000..a826026ec --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules-malformed-rule.rs @@ -0,0 +1,11 @@ +#![deny(unused_macro_rules)] + +macro_rules! foo { + (v) => {}; + (w) => {}; + () => 0; //~ ERROR: macro rhs must be delimited +} + +fn main() { + foo!(v); +} diff --git a/src/test/ui/lint/unused/unused-macro-rules-malformed-rule.stderr b/src/test/ui/lint/unused/unused-macro-rules-malformed-rule.stderr new file mode 100644 index 000000000..797c86710 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules-malformed-rule.stderr @@ -0,0 +1,8 @@ +error: macro rhs must be delimited + --> $DIR/unused-macro-rules-malformed-rule.rs:6:11 + | +LL | () => 0; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/unused-macro-rules.rs b/src/test/ui/lint/unused/unused-macro-rules.rs new file mode 100644 index 000000000..eeaf4d1b0 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules.rs @@ -0,0 +1,47 @@ +#![deny(unused_macro_rules)] +// To make sure we are not hitting this +#![deny(unused_macros)] + +// Most simple case +macro_rules! num { + (one) => { 1 }; + (two) => { 2 }; //~ ERROR: 2nd rule of macro + (three) => { 3 }; + (four) => { 4 }; //~ ERROR: 4th rule of macro +} +const _NUM: u8 = num!(one) + num!(three); + +// Check that allowing the lint works +#[allow(unused_macro_rules)] +macro_rules! num_allowed { + (one) => { 1 }; + (two) => { 2 }; + (three) => { 3 }; + (four) => { 4 }; +} +const _NUM_ALLOWED: u8 = num_allowed!(one) + num_allowed!(three); + +// Check that macro calls inside the macro trigger as usage +macro_rules! num_rec { + (one) => { 1 }; + (two) => { + num_rec!(one) + num_rec!(one) + }; + (three) => { //~ ERROR: 3rd rule of macro + num_rec!(one) + num_rec!(two) + }; + (four) => { num_rec!(two) + num_rec!(two) }; +} +const _NUM_RECURSIVE: u8 = num_rec!(four); + +// No error if the macro is being exported +#[macro_export] +macro_rules! num_exported { + (one) => { 1 }; + (two) => { 2 }; + (three) => { 3 }; + (four) => { 4 }; +} +const _NUM_EXPORTED: u8 = num_exported!(one) + num_exported!(three); + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-macro-rules.stderr b/src/test/ui/lint/unused/unused-macro-rules.stderr new file mode 100644 index 000000000..2b3098a51 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-rules.stderr @@ -0,0 +1,26 @@ +error: 4th rule of macro `num` is never used + --> $DIR/unused-macro-rules.rs:10:5 + | +LL | (four) => { 4 }; + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macro-rules.rs:1:9 + | +LL | #![deny(unused_macro_rules)] + | ^^^^^^^^^^^^^^^^^^ + +error: 2nd rule of macro `num` is never used + --> $DIR/unused-macro-rules.rs:8:5 + | +LL | (two) => { 2 }; + | ^^^^^ + +error: 3rd rule of macro `num_rec` is never used + --> $DIR/unused-macro-rules.rs:30:5 + | +LL | (three) => { + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs new file mode 100644 index 000000000..ce187047b --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs @@ -0,0 +1,9 @@ +#![allow(unused_macros)] + +// Issue #21370 + +macro_rules! test { + ($wrong:t_ty) => () //~ ERROR invalid fragment specifier `t_ty` +} + +fn main() { } diff --git a/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr new file mode 100644 index 000000000..6edf0a2cf --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr @@ -0,0 +1,10 @@ +error: invalid fragment specifier `t_ty` + --> $DIR/unused-macro-with-bad-frag-spec.rs:6:6 + | +LL | ($wrong:t_ty) => () + | ^^^^^^^^^^^ + | + = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/unused-macro-with-follow-violation.rs b/src/test/ui/lint/unused/unused-macro-with-follow-violation.rs new file mode 100644 index 000000000..1666dae69 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-with-follow-violation.rs @@ -0,0 +1,7 @@ +#![allow(unused_macros)] + +macro_rules! test { + ($e:expr +) => () //~ ERROR not allowed for `expr` fragments +} + +fn main() { } diff --git a/src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr b/src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr new file mode 100644 index 000000000..5eced4f06 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr @@ -0,0 +1,10 @@ +error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments + --> $DIR/unused-macro-with-follow-violation.rs:4:14 + | +LL | ($e:expr +) => () + | ^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/unused-macros-decl.rs b/src/test/ui/lint/unused/unused-macros-decl.rs new file mode 100644 index 000000000..21f6108b1 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macros-decl.rs @@ -0,0 +1,28 @@ +#![feature(decl_macro)] +#![deny(unused_macros)] +// To make sure we are not hitting this +#![deny(unused_macro_rules)] + +// Most simple case +macro unused { //~ ERROR: unused macro definition + () => {} +} + +#[allow(unused_macros)] +mod bar { + // Test that putting the #[deny] close to the macro's definition + // works. + + #[deny(unused_macros)] + macro unused { //~ ERROR: unused macro definition + () => {} + } +} + +mod boo { + pub(crate) macro unused { //~ ERROR: unused macro definition + () => {} + } +} + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-macros-decl.stderr b/src/test/ui/lint/unused/unused-macros-decl.stderr new file mode 100644 index 000000000..1f426b9d9 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macros-decl.stderr @@ -0,0 +1,32 @@ +error: unused macro definition: `unused` + --> $DIR/unused-macros-decl.rs:7:7 + | +LL | macro unused { + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macros-decl.rs:2:9 + | +LL | #![deny(unused_macros)] + | ^^^^^^^^^^^^^ + +error: unused macro definition: `unused` + --> $DIR/unused-macros-decl.rs:17:11 + | +LL | macro unused { + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macros-decl.rs:16:12 + | +LL | #[deny(unused_macros)] + | ^^^^^^^^^^^^^ + +error: unused macro definition: `unused` + --> $DIR/unused-macros-decl.rs:23:22 + | +LL | pub(crate) macro unused { + | ^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/lint/unused/unused-macros-malformed-rule.rs b/src/test/ui/lint/unused/unused-macros-malformed-rule.rs new file mode 100644 index 000000000..d4c35fad9 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macros-malformed-rule.rs @@ -0,0 +1,15 @@ +#![deny(unused_macros)] + +macro_rules! foo { //~ ERROR: unused macro definition + (v) => {}; + () => 0; //~ ERROR: macro rhs must be delimited +} + +macro_rules! bar { + (v) => {}; + () => 0; //~ ERROR: macro rhs must be delimited +} + +fn main() { + bar!(v); +} diff --git a/src/test/ui/lint/unused/unused-macros-malformed-rule.stderr b/src/test/ui/lint/unused/unused-macros-malformed-rule.stderr new file mode 100644 index 000000000..9a880dccf --- /dev/null +++ b/src/test/ui/lint/unused/unused-macros-malformed-rule.stderr @@ -0,0 +1,26 @@ +error: macro rhs must be delimited + --> $DIR/unused-macros-malformed-rule.rs:5:11 + | +LL | () => 0; + | ^ + +error: macro rhs must be delimited + --> $DIR/unused-macros-malformed-rule.rs:10:11 + | +LL | () => 0; + | ^ + +error: unused macro definition: `foo` + --> $DIR/unused-macros-malformed-rule.rs:3:14 + | +LL | macro_rules! foo { + | ^^^ + | +note: the lint level is defined here + --> $DIR/unused-macros-malformed-rule.rs:1:9 + | +LL | #![deny(unused_macros)] + | ^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/lint/unused/unused-macros.rs b/src/test/ui/lint/unused/unused-macros.rs new file mode 100644 index 000000000..70b50b208 --- /dev/null +++ b/src/test/ui/lint/unused/unused-macros.rs @@ -0,0 +1,31 @@ +#![deny(unused_macros)] +// To make sure we are not hitting this +#![deny(unused_macro_rules)] + +// Most simple case +macro_rules! unused { //~ ERROR: unused macro definition + () => {}; +} + +// Test macros created by macros +macro_rules! create_macro { + () => { + macro_rules! m { //~ ERROR: unused macro definition + () => {}; + } + }; +} +create_macro!(); + +#[allow(unused_macros)] +mod bar { + // Test that putting the #[deny] close to the macro's definition + // works. + + #[deny(unused_macros)] + macro_rules! unused { //~ ERROR: unused macro definition + () => {}; + } +} + +fn main() {} diff --git a/src/test/ui/lint/unused/unused-macros.stderr b/src/test/ui/lint/unused/unused-macros.stderr new file mode 100644 index 000000000..d0baf5bec --- /dev/null +++ b/src/test/ui/lint/unused/unused-macros.stderr @@ -0,0 +1,32 @@ +error: unused macro definition: `unused` + --> $DIR/unused-macros.rs:6:14 + | +LL | macro_rules! unused { + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macros.rs:1:9 + | +LL | #![deny(unused_macros)] + | ^^^^^^^^^^^^^ + +error: unused macro definition: `m` + --> $DIR/unused-macros.rs:13:22 + | +LL | macro_rules! m { + | ^ + +error: unused macro definition: `unused` + --> $DIR/unused-macros.rs:26:18 + | +LL | macro_rules! unused { + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macros.rs:25:12 + | +LL | #[deny(unused_macros)] + | ^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed b/src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed new file mode 100644 index 000000000..c21f18015 --- /dev/null +++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +#![forbid(unused_mut)] + +fn main() { + let x = 1; + //~^ ERROR: variable does not need to be mutable + (move|| { println!("{}", x); })(); +} diff --git a/src/test/ui/lint/unused/unused-mut-warning-captured-var.rs b/src/test/ui/lint/unused/unused-mut-warning-captured-var.rs new file mode 100644 index 000000000..3119d83a0 --- /dev/null +++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.rs @@ -0,0 +1,9 @@ +// run-rustfix + +#![forbid(unused_mut)] + +fn main() { + let mut x = 1; + //~^ ERROR: variable does not need to be mutable + (move|| { println!("{}", x); })(); +} diff --git a/src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr b/src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr new file mode 100644 index 000000000..20aeedcc2 --- /dev/null +++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr @@ -0,0 +1,16 @@ +error: variable does not need to be mutable + --> $DIR/unused-mut-warning-captured-var.rs:6:9 + | +LL | let mut x = 1; + | ----^ + | | + | help: remove this `mut` + | +note: the lint level is defined here + --> $DIR/unused-mut-warning-captured-var.rs:3:11 + | +LL | #![forbid(unused_mut)] + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/unused-result.rs b/src/test/ui/lint/unused/unused-result.rs new file mode 100644 index 000000000..e283eaa88 --- /dev/null +++ b/src/test/ui/lint/unused/unused-result.rs @@ -0,0 +1,42 @@ +#![allow(dead_code)] +#![deny(unused_results, unused_must_use)] +//~^ NOTE: the lint level is defined here +//~| NOTE: the lint level is defined here + +#[must_use] +enum MustUse { Test } + +#[must_use = "some message"] +enum MustUseMsg { Test2 } + +fn foo<T>() -> T { panic!() } + +fn bar() -> isize { return foo::<isize>(); } +fn baz() -> MustUse { return foo::<MustUse>(); } +fn qux() -> MustUseMsg { return foo::<MustUseMsg>(); } + +#[allow(unused_results)] +fn test() { + foo::<isize>(); + foo::<MustUse>(); //~ ERROR: unused `MustUse` that must be used + foo::<MustUseMsg>(); //~ ERROR: unused `MustUseMsg` that must be used + //~^ NOTE: some message +} + +#[allow(unused_results, unused_must_use)] +fn test2() { + foo::<isize>(); + foo::<MustUse>(); + foo::<MustUseMsg>(); +} + +fn main() { + foo::<isize>(); //~ ERROR: unused result of type `isize` + foo::<MustUse>(); //~ ERROR: unused `MustUse` that must be used + foo::<MustUseMsg>(); //~ ERROR: unused `MustUseMsg` that must be used + //~^ NOTE: some message + + let _ = foo::<isize>(); + let _ = foo::<MustUse>(); + let _ = foo::<MustUseMsg>(); +} diff --git a/src/test/ui/lint/unused/unused-result.stderr b/src/test/ui/lint/unused/unused-result.stderr new file mode 100644 index 000000000..087e06341 --- /dev/null +++ b/src/test/ui/lint/unused/unused-result.stderr @@ -0,0 +1,48 @@ +error: unused `MustUse` that must be used + --> $DIR/unused-result.rs:21:5 + | +LL | foo::<MustUse>(); + | ^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-result.rs:2:25 + | +LL | #![deny(unused_results, unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: unused `MustUseMsg` that must be used + --> $DIR/unused-result.rs:22:5 + | +LL | foo::<MustUseMsg>(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: some message + +error: unused result of type `isize` + --> $DIR/unused-result.rs:34:5 + | +LL | foo::<isize>(); + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-result.rs:2:9 + | +LL | #![deny(unused_results, unused_must_use)] + | ^^^^^^^^^^^^^^ + +error: unused `MustUse` that must be used + --> $DIR/unused-result.rs:35:5 + | +LL | foo::<MustUse>(); + | ^^^^^^^^^^^^^^^^^ + +error: unused `MustUseMsg` that must be used + --> $DIR/unused-result.rs:36:5 + | +LL | foo::<MustUseMsg>(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: some message + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.rs b/src/test/ui/lint/unused/unused_attributes-must_use.rs new file mode 100644 index 000000000..1c4abb949 --- /dev/null +++ b/src/test/ui/lint/unused/unused_attributes-must_use.rs @@ -0,0 +1,125 @@ +#![allow(dead_code, path_statements)] +#![deny(unused_attributes, unused_must_use)] +#![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)] + +#[must_use] //~ ERROR `#[must_use]` has no effect +extern crate std as std2; + +#[must_use] //~ ERROR `#[must_use]` has no effect +mod test_mod {} + +#[must_use] //~ ERROR `#[must_use]` has no effect +use std::arch::global_asm; + +#[must_use] //~ ERROR `#[must_use]` has no effect +const CONST: usize = 4; +#[must_use] //~ ERROR `#[must_use]` has no effect +#[no_mangle] +static STATIC: usize = 4; + +#[must_use] +struct X; + +#[must_use] +enum Y { + Z, +} + +#[must_use] +union U { + unit: (), +} + +#[must_use] //~ ERROR `#[must_use]` has no effect +impl U { + #[must_use] + fn method() -> i32 { + 4 + } +} + +#[must_use] +#[no_mangle] +fn foo() -> i64 { + 4 +} + +#[must_use] //~ ERROR `#[must_use]` has no effect +extern "Rust" { + #[link_name = "STATIC"] + #[must_use] //~ ERROR `#[must_use]` has no effect + static FOREIGN_STATIC: usize; + + #[link_name = "foo"] + #[must_use] + fn foreign_foo() -> i64; +} + +#[must_use] //~ ERROR unused attribute +global_asm!(""); + +#[must_use] //~ ERROR `#[must_use]` has no effect +type UseMe = (); + +fn qux<#[must_use] T>(_: T) {} //~ ERROR `#[must_use]` has no effect + +#[must_use] +trait Use { + #[must_use] //~ ERROR `#[must_use]` has no effect + const ASSOC_CONST: usize = 4; + #[must_use] //~ ERROR `#[must_use]` has no effect + type AssocTy; + + #[must_use] + fn get_four(&self) -> usize { + 4 + } +} + +#[must_use] //~ ERROR `#[must_use]` has no effect +impl Use for () { + type AssocTy = (); +} + +#[must_use] //~ ERROR `#[must_use]` has no effect +trait Alias = Use; + +#[must_use] //~ ERROR `#[must_use]` has no effect +macro_rules! cool_macro { + () => { + 4 + }; +} + +fn main() { + #[must_use] //~ ERROR `#[must_use]` has no effect + let x = || {}; + x(); + + let x = #[must_use] //~ ERROR `#[must_use]` has no effect + || {}; + x(); + + X; //~ ERROR that must be used + Y::Z; //~ ERROR that must be used + U { unit: () }; //~ ERROR that must be used + U::method(); //~ ERROR that must be used + foo(); //~ ERROR that must be used + + unsafe { + foreign_foo(); //~ ERROR that must be used + }; + + CONST; + STATIC; + unsafe { FOREIGN_STATIC }; + cool_macro!(); + qux(4); + ().get_four(); //~ ERROR that must be used + + match Some(4) { + #[must_use] //~ ERROR `#[must_use]` has no effect + Some(res) => res, + None => 0, + }; +} diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr new file mode 100644 index 000000000..317d81c59 --- /dev/null +++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr @@ -0,0 +1,175 @@ +error: unused attribute `must_use` + --> $DIR/unused_attributes-must_use.rs:58:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused_attributes-must_use.rs:2:9 + | +LL | #![deny(unused_attributes, unused_must_use)] + | ^^^^^^^^^^^^^^^^^ +note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm` + --> $DIR/unused_attributes-must_use.rs:59:1 + | +LL | global_asm!(""); + | ^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to an extern crate + --> $DIR/unused_attributes-must_use.rs:5:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a module + --> $DIR/unused_attributes-must_use.rs:8:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a use + --> $DIR/unused_attributes-must_use.rs:11:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a constant item + --> $DIR/unused_attributes-must_use.rs:14:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a static item + --> $DIR/unused_attributes-must_use.rs:16:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to an implementation block + --> $DIR/unused_attributes-must_use.rs:33:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a foreign module + --> $DIR/unused_attributes-must_use.rs:47:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a type alias + --> $DIR/unused_attributes-must_use.rs:61:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a type parameter + --> $DIR/unused_attributes-must_use.rs:64:8 + | +LL | fn qux<#[must_use] T>(_: T) {} + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to an implementation block + --> $DIR/unused_attributes-must_use.rs:79:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a trait alias + --> $DIR/unused_attributes-must_use.rs:84:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a macro def + --> $DIR/unused_attributes-must_use.rs:87:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a statement + --> $DIR/unused_attributes-must_use.rs:95:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a closure + --> $DIR/unused_attributes-must_use.rs:99:13 + | +LL | let x = #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to an match arm + --> $DIR/unused_attributes-must_use.rs:121:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to an associated const + --> $DIR/unused_attributes-must_use.rs:68:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to an associated type + --> $DIR/unused_attributes-must_use.rs:70:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: `#[must_use]` has no effect when applied to a foreign static item + --> $DIR/unused_attributes-must_use.rs:50:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + +error: unused `X` that must be used + --> $DIR/unused_attributes-must_use.rs:103:5 + | +LL | X; + | ^^ + | +note: the lint level is defined here + --> $DIR/unused_attributes-must_use.rs:2:28 + | +LL | #![deny(unused_attributes, unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: unused `Y` that must be used + --> $DIR/unused_attributes-must_use.rs:104:5 + | +LL | Y::Z; + | ^^^^^ + +error: unused `U` that must be used + --> $DIR/unused_attributes-must_use.rs:105:5 + | +LL | U { unit: () }; + | ^^^^^^^^^^^^^^^ + +error: unused return value of `U::method` that must be used + --> $DIR/unused_attributes-must_use.rs:106:5 + | +LL | U::method(); + | ^^^^^^^^^^^^ + +error: unused return value of `foo` that must be used + --> $DIR/unused_attributes-must_use.rs:107:5 + | +LL | foo(); + | ^^^^^^ + +error: unused return value of `foreign_foo` that must be used + --> $DIR/unused_attributes-must_use.rs:110:9 + | +LL | foreign_foo(); + | ^^^^^^^^^^^^^^ + +error: unused return value of `Use::get_four` that must be used + --> $DIR/unused_attributes-must_use.rs:118:5 + | +LL | ().get_four(); + | ^^^^^^^^^^^^^^ + +error: aborting due to 26 previous errors + diff --git a/src/test/ui/lint/unused/useless-comment.rs b/src/test/ui/lint/unused/useless-comment.rs new file mode 100644 index 000000000..7d2e5ab6f --- /dev/null +++ b/src/test/ui/lint/unused/useless-comment.rs @@ -0,0 +1,45 @@ +#![feature(stmt_expr_attributes)] + +#![deny(unused_doc_comments)] + +macro_rules! mac { + () => {} +} + +/// foo //~ ERROR unused doc comment +mac!(); + +fn foo() { + /// a //~ ERROR unused doc comment + let x = 12; + + /// multi-line //~ unused doc comment + /// doc comment + /// that is unused + match x { + /// c //~ ERROR unused doc comment + 1 => {}, + _ => {} + } + + /// foo //~ ERROR unused doc comment + unsafe {} + + #[doc = "foo"] //~ ERROR unused doc comment + #[doc = "bar"] //~ ERROR unused doc comment + 3; + + /// bar //~ ERROR unused doc comment + mac!(); + + let x = /** comment */ 47; //~ ERROR unused doc comment + + /// dox //~ ERROR unused doc comment + { + + } +} + +fn main() { + foo(); +} diff --git a/src/test/ui/lint/unused/useless-comment.stderr b/src/test/ui/lint/unused/useless-comment.stderr new file mode 100644 index 000000000..0054426fb --- /dev/null +++ b/src/test/ui/lint/unused/useless-comment.stderr @@ -0,0 +1,110 @@ +error: unused doc comment + --> $DIR/useless-comment.rs:9:1 + | +LL | /// foo + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations + | +note: the lint level is defined here + --> $DIR/useless-comment.rs:3:9 + | +LL | #![deny(unused_doc_comments)] + | ^^^^^^^^^^^^^^^^^^^ + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion + +error: unused doc comment + --> $DIR/useless-comment.rs:32:5 + | +LL | /// bar + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations + | + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion + +error: unused doc comment + --> $DIR/useless-comment.rs:13:5 + | +LL | /// a + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let x = 12; + | ----------- rustdoc does not generate documentation for statements + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/useless-comment.rs:16:5 + | +LL | / /// multi-line +LL | | /// doc comment +LL | | /// that is unused + | |______________________^ +LL | / match x { +LL | | /// c +LL | | 1 => {}, +LL | | _ => {} +LL | | } + | |_____- rustdoc does not generate documentation for expressions + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/useless-comment.rs:20:9 + | +LL | /// c + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | 1 => {}, + | ------- rustdoc does not generate documentation for match arms + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/useless-comment.rs:25:5 + | +LL | /// foo + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe {} + | --------- rustdoc does not generate documentation for expressions + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/useless-comment.rs:28:5 + | +LL | #[doc = "foo"] + | ^^^^^^^^^^^^^^ +LL | #[doc = "bar"] +LL | 3; + | - rustdoc does not generate documentation for expressions + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/useless-comment.rs:29:5 + | +LL | #[doc = "bar"] + | ^^^^^^^^^^^^^^ +LL | 3; + | - rustdoc does not generate documentation for expressions + | + = help: use `//` for a plain comment + +error: unused doc comment + --> $DIR/useless-comment.rs:35:13 + | +LL | let x = /** comment */ 47; + | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions + | + = help: use `/* */` for a plain comment + +error: unused doc comment + --> $DIR/useless-comment.rs:37:5 + | +LL | /// dox + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / { +LL | | +LL | | } + | |_____- rustdoc does not generate documentation for expressions + | + = help: use `//` for a plain comment + +error: aborting due to 10 previous errors + |