diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:06:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:06:31 +0000 |
commit | 2ff14448863ac1a1dd9533461708e29aae170c2d (patch) | |
tree | 85b9fea2bbfe3f06473cfa381eed11f273b57c5c /src/tools/clippy/tests/ui | |
parent | Adding debian version 1.64.0+dfsg1-1. (diff) | |
download | rustc-2ff14448863ac1a1dd9533461708e29aae170c2d.tar.xz rustc-2ff14448863ac1a1dd9533461708e29aae170c2d.zip |
Adding debian version 1.65.0+dfsg1-2.debian/1.65.0+dfsg1-2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/clippy/tests/ui')
234 files changed, 6226 insertions, 1206 deletions
diff --git a/src/tools/clippy/tests/ui/arithmetic.fixed b/src/tools/clippy/tests/ui/arithmetic.fixed deleted file mode 100644 index a2a1c4394..000000000 --- a/src/tools/clippy/tests/ui/arithmetic.fixed +++ /dev/null @@ -1,27 +0,0 @@ -// run-rustfix - -#![allow(clippy::unnecessary_owned_empty_strings)] -#![feature(saturating_int_impl)] -#![warn(clippy::arithmetic)] - -use core::num::{Saturating, Wrapping}; - -pub fn hard_coded_allowed() { - let _ = Saturating(0u32) + Saturating(0u32); - let _ = String::new() + ""; - let _ = Wrapping(0u32) + Wrapping(0u32); - - let saturating: Saturating<u32> = Saturating(0u32); - let string: String = String::new(); - let wrapping: Wrapping<u32> = Wrapping(0u32); - - let inferred_saturating = saturating + saturating; - let inferred_string = string + ""; - let inferred_wrapping = wrapping + wrapping; - - let _ = inferred_saturating + inferred_saturating; - let _ = inferred_string + ""; - let _ = inferred_wrapping + inferred_wrapping; -} - -fn main() {} diff --git a/src/tools/clippy/tests/ui/arithmetic.rs b/src/tools/clippy/tests/ui/arithmetic.rs deleted file mode 100644 index a2a1c4394..000000000 --- a/src/tools/clippy/tests/ui/arithmetic.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-rustfix - -#![allow(clippy::unnecessary_owned_empty_strings)] -#![feature(saturating_int_impl)] -#![warn(clippy::arithmetic)] - -use core::num::{Saturating, Wrapping}; - -pub fn hard_coded_allowed() { - let _ = Saturating(0u32) + Saturating(0u32); - let _ = String::new() + ""; - let _ = Wrapping(0u32) + Wrapping(0u32); - - let saturating: Saturating<u32> = Saturating(0u32); - let string: String = String::new(); - let wrapping: Wrapping<u32> = Wrapping(0u32); - - let inferred_saturating = saturating + saturating; - let inferred_string = string + ""; - let inferred_wrapping = wrapping + wrapping; - - let _ = inferred_saturating + inferred_saturating; - let _ = inferred_string + ""; - let _ = inferred_wrapping + inferred_wrapping; -} - -fn main() {} diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs new file mode 100644 index 000000000..f5390c746 --- /dev/null +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs @@ -0,0 +1,57 @@ +#![allow(clippy::assign_op_pattern, clippy::unnecessary_owned_empty_strings)] +#![feature(inline_const, saturating_int_impl)] +#![warn(clippy::arithmetic_side_effects)] + +use core::num::{Saturating, Wrapping}; + +pub fn hard_coded_allowed() { + let _ = 1f32 + 1f32; + let _ = 1f64 + 1f64; + + let _ = Saturating(0u32) + Saturating(0u32); + let _ = String::new() + ""; + let _ = Wrapping(0u32) + Wrapping(0u32); + + let saturating: Saturating<u32> = Saturating(0u32); + let string: String = String::new(); + let wrapping: Wrapping<u32> = Wrapping(0u32); + + let inferred_saturating = saturating + saturating; + let inferred_string = string + ""; + let inferred_wrapping = wrapping + wrapping; + + let _ = inferred_saturating + inferred_saturating; + let _ = inferred_string + ""; + let _ = inferred_wrapping + inferred_wrapping; +} + +#[rustfmt::skip] +pub fn non_overflowing_ops() { + const _: i32 = { let mut n = 1; n += 1; n }; + let _ = const { let mut n = 1; n += 1; n }; + + const _: i32 = { let mut n = 1; n = n + 1; n }; + let _ = const { let mut n = 1; n = n + 1; n }; + + const _: i32 = { let mut n = 1; n = 1 + n; n }; + let _ = const { let mut n = 1; n = 1 + n; n }; + + const _: i32 = 1 + 1; + let _ = 1 + 1; + let _ = const { 1 + 1 }; + + let mut _a = 1; + _a *= 1; + _a /= 1; +} + +#[rustfmt::skip] +pub fn overflowing_ops() { + let mut _a = 1; _a += 1; + + let mut _b = 1; _b = _b + 1; + + let mut _c = 1; _c = 1 + _c; +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr new file mode 100644 index 000000000..6c4c8bdec --- /dev/null +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr @@ -0,0 +1,22 @@ +error: arithmetic detected + --> $DIR/arithmetic_side_effects.rs:50:21 + | +LL | let mut _a = 1; _a += 1; + | ^^^^^^^ + | + = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` + +error: arithmetic detected + --> $DIR/arithmetic_side_effects.rs:52:26 + | +LL | let mut _b = 1; _b = _b + 1; + | ^^^^^^ + +error: arithmetic detected + --> $DIR/arithmetic_side_effects.rs:54:26 + | +LL | let mut _c = 1; _c = 1 + _c; + | ^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed index 7bde72e4b..795f435f2 100644 --- a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed +++ b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed @@ -27,6 +27,14 @@ fn main() { let r: Result<Foo, Foo> = Ok(Foo); assert!(r.is_ok()); + // test ok with some messages + let r: Result<Foo, DebugFoo> = Ok(Foo); + assert!(r.is_ok(), "oops"); + + // test ok with unit error + let r: Result<Foo, ()> = Ok(Foo); + assert!(r.is_ok()); + // test temporary ok fn get_ok() -> Result<Foo, DebugFoo> { Ok(Foo) diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.rs b/src/tools/clippy/tests/ui/assertions_on_result_states.rs index 4c5af81ef..1101aec1e 100644 --- a/src/tools/clippy/tests/ui/assertions_on_result_states.rs +++ b/src/tools/clippy/tests/ui/assertions_on_result_states.rs @@ -27,6 +27,14 @@ fn main() { let r: Result<Foo, Foo> = Ok(Foo); assert!(r.is_ok()); + // test ok with some messages + let r: Result<Foo, DebugFoo> = Ok(Foo); + assert!(r.is_ok(), "oops"); + + // test ok with unit error + let r: Result<Foo, ()> = Ok(Foo); + assert!(r.is_ok()); + // test temporary ok fn get_ok() -> Result<Foo, DebugFoo> { Ok(Foo) diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr index 13c2dd877..97a5f3dfc 100644 --- a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr +++ b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr @@ -7,31 +7,31 @@ LL | assert!(r.is_ok()); = note: `-D clippy::assertions-on-result-states` implied by `-D warnings` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:34:5 + --> $DIR/assertions_on_result_states.rs:42:5 | LL | assert!(get_ok().is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok().unwrap()` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:37:5 + --> $DIR/assertions_on_result_states.rs:45:5 | LL | assert!(get_ok_macro!().is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok_macro!().unwrap()` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:50:5 + --> $DIR/assertions_on_result_states.rs:58:5 | LL | assert!(r.is_ok()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:56:9 + --> $DIR/assertions_on_result_states.rs:64:9 | LL | assert!(r.is_ok()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()` error: called `assert!` with `Result::is_err` - --> $DIR/assertions_on_result_states.rs:64:5 + --> $DIR/assertions_on_result_states.rs:72:5 | LL | assert!(r.is_err()); | ^^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap_err()` diff --git a/src/tools/clippy/tests/ui/author.stdout b/src/tools/clippy/tests/ui/author.stdout index 312586303..597318a55 100644 --- a/src/tools/clippy/tests/ui/author.stdout +++ b/src/tools/clippy/tests/ui/author.stdout @@ -6,7 +6,7 @@ if_chain! { if match_qpath(qpath, &["char"]); if let ExprKind::Lit(ref lit) = expr.kind; if let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node; - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind; if name.as_str() == "x"; then { // report your lint here diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout index 2fc4a7d1f..a529981e2 100644 --- a/src/tools/clippy/tests/ui/author/blocks.stdout +++ b/src/tools/clippy/tests/ui/author/blocks.stdout @@ -5,13 +5,13 @@ if_chain! { if let Some(init) = local.init; if let ExprKind::Lit(ref lit) = init.kind; if let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node; - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind; if name.as_str() == "x"; if let StmtKind::Local(local1) = block.stmts[1].kind; if let Some(init1) = local1.init; if let ExprKind::Lit(ref lit1) = init1.kind; if let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node; - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local1.pat.kind; if name1.as_str() == "_t"; if let StmtKind::Semi(e) = block.stmts[2].kind; if let ExprKind::Unary(UnOp::Neg, inner) = e.kind; @@ -31,7 +31,7 @@ if_chain! { if let ExprKind::Path(ref qpath) = func.kind; if match_qpath(qpath, &["String", "new"]); if args.is_empty(); - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind; if name.as_str() == "expr"; if let Some(trailing_expr) = block.expr; if let ExprKind::Call(func1, args1) = trailing_expr.kind; diff --git a/src/tools/clippy/tests/ui/author/loop.stdout b/src/tools/clippy/tests/ui/author/loop.stdout index 3d9560f69..ceb53fcd4 100644 --- a/src/tools/clippy/tests/ui/author/loop.stdout +++ b/src/tools/clippy/tests/ui/author/loop.stdout @@ -1,6 +1,6 @@ if_chain! { if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr); - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = pat.kind; if name.as_str() == "y"; if let ExprKind::Struct(qpath, fields, None) = arg.kind; if matches!(qpath, QPath::LangItem(LangItem::Range, _)); @@ -17,7 +17,7 @@ if_chain! { if let Some(init) = local.init; if let ExprKind::Path(ref qpath1) = init.kind; if match_qpath(qpath1, &["y"]); - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind; if name1.as_str() == "z"; if block.expr.is_none(); then { diff --git a/src/tools/clippy/tests/ui/author/matches.stdout b/src/tools/clippy/tests/ui/author/matches.stdout index 38444a009..2cf69a035 100644 --- a/src/tools/clippy/tests/ui/author/matches.stdout +++ b/src/tools/clippy/tests/ui/author/matches.stdout @@ -21,7 +21,7 @@ if_chain! { if let Some(init1) = local1.init; if let ExprKind::Lit(ref lit4) = init1.kind; if let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node; - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local1.pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local1.pat.kind; if name.as_str() == "x"; if let Some(trailing_expr) = block.expr; if let ExprKind::Path(ref qpath) = trailing_expr.kind; @@ -30,7 +30,7 @@ if_chain! { if arms[2].guard.is_none(); if let ExprKind::Lit(ref lit5) = arms[2].body.kind; if let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node; - if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind; + if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind; if name1.as_str() == "a"; then { // report your lint here diff --git a/src/tools/clippy/tests/ui/author/struct.rs b/src/tools/clippy/tests/ui/author/struct.rs index 5fdf3433a..a99bdfc13 100644 --- a/src/tools/clippy/tests/ui/author/struct.rs +++ b/src/tools/clippy/tests/ui/author/struct.rs @@ -1,4 +1,9 @@ -#[allow(clippy::unnecessary_operation, clippy::single_match)] +#![allow( + clippy::unnecessary_operation, + clippy::single_match, + clippy::no_effect, + clippy::bool_to_int_with_if +)] fn main() { struct Test { field: u32, diff --git a/src/tools/clippy/tests/ui/author/struct.stdout b/src/tools/clippy/tests/ui/author/struct.stdout index 5e78b7c9d..b5bbc9e21 100644 --- a/src/tools/clippy/tests/ui/author/struct.stdout +++ b/src/tools/clippy/tests/ui/author/struct.stdout @@ -53,11 +53,11 @@ if_chain! { } } if_chain! { - if let ExprKind::MethodCall(method_name, args, _) = expr.kind; + if let ExprKind::MethodCall(method_name, receiver, args, _) = expr.kind; if method_name.ident.as_str() == "test"; - if args.len() == 1; - if let ExprKind::Path(ref qpath) = args[0].kind; + if let ExprKind::Path(ref qpath) = receiver.kind; if match_qpath(qpath, &["test_method_call"]); + if args.is_empty(); then { // report your lint here } diff --git a/src/tools/clippy/tests/ui/blacklisted_name.stderr b/src/tools/clippy/tests/ui/blacklisted_name.stderr deleted file mode 100644 index 70dbdaece..000000000 --- a/src/tools/clippy/tests/ui/blacklisted_name.stderr +++ /dev/null @@ -1,88 +0,0 @@ -error: use of a blacklisted/placeholder name `foo` - --> $DIR/blacklisted_name.rs:11:9 - | -LL | fn test(foo: ()) {} - | ^^^ - | - = note: `-D clippy::blacklisted-name` implied by `-D warnings` - -error: use of a blacklisted/placeholder name `foo` - --> $DIR/blacklisted_name.rs:14:9 - | -LL | let foo = 42; - | ^^^ - -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:15:9 - | -LL | let baz = 42; - | ^^^ - -error: use of a blacklisted/placeholder name `quux` - --> $DIR/blacklisted_name.rs:16:9 - | -LL | let quux = 42; - | ^^^^ - -error: use of a blacklisted/placeholder name `foo` - --> $DIR/blacklisted_name.rs:27:10 - | -LL | (foo, Some(baz), quux @ Some(_)) => (), - | ^^^ - -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:27:20 - | -LL | (foo, Some(baz), quux @ Some(_)) => (), - | ^^^ - -error: use of a blacklisted/placeholder name `quux` - --> $DIR/blacklisted_name.rs:27:26 - | -LL | (foo, Some(baz), quux @ Some(_)) => (), - | ^^^^ - -error: use of a blacklisted/placeholder name `foo` - --> $DIR/blacklisted_name.rs:32:19 - | -LL | fn issue_1647(mut foo: u8) { - | ^^^ - -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:33:13 - | -LL | let mut baz = 0; - | ^^^ - -error: use of a blacklisted/placeholder name `quux` - --> $DIR/blacklisted_name.rs:34:21 - | -LL | if let Some(mut quux) = Some(42) {} - | ^^^^ - -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:38:13 - | -LL | let ref baz = 0; - | ^^^ - -error: use of a blacklisted/placeholder name `quux` - --> $DIR/blacklisted_name.rs:39:21 - | -LL | if let Some(ref quux) = Some(42) {} - | ^^^^ - -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:43:17 - | -LL | let ref mut baz = 0; - | ^^^ - -error: use of a blacklisted/placeholder name `quux` - --> $DIR/blacklisted_name.rs:44:25 - | -LL | if let Some(ref mut quux) = Some(42) {} - | ^^^^ - -error: aborting due to 14 previous errors - diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed new file mode 100644 index 000000000..9c1098dc4 --- /dev/null +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed @@ -0,0 +1,85 @@ +// run-rustfix + +#![warn(clippy::bool_to_int_with_if)] +#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] + +fn main() { + let a = true; + let b = false; + + let x = 1; + let y = 2; + + // Should lint + // precedence + i32::from(a); + i32::from(!a); + i32::from(a || b); + i32::from(cond(a, b)); + i32::from(x + y < 4); + + // if else if + if a { + 123 + } else {i32::from(b)}; + + // Shouldn't lint + + if a { + 1 + } else if b { + 0 + } else { + 3 + }; + + if a { + 3 + } else if b { + 1 + } else { + -2 + }; + + if a { + 3 + } else { + 0 + }; + if a { + side_effect(); + 1 + } else { + 0 + }; + if a { + 1 + } else { + side_effect(); + 0 + }; + + // multiple else ifs + if a { + 123 + } else if b { + 1 + } else if a | b { + 0 + } else { + 123 + }; + + some_fn(a); +} + +// Lint returns and type inference +fn some_fn(a: bool) -> u8 { + u8::from(a) +} + +fn side_effect() {} + +fn cond(a: bool, b: bool) -> bool { + a || b +} diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs new file mode 100644 index 000000000..0c967dac6 --- /dev/null +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs @@ -0,0 +1,109 @@ +// run-rustfix + +#![warn(clippy::bool_to_int_with_if)] +#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] + +fn main() { + let a = true; + let b = false; + + let x = 1; + let y = 2; + + // Should lint + // precedence + if a { + 1 + } else { + 0 + }; + if !a { + 1 + } else { + 0 + }; + if a || b { + 1 + } else { + 0 + }; + if cond(a, b) { + 1 + } else { + 0 + }; + if x + y < 4 { + 1 + } else { + 0 + }; + + // if else if + if a { + 123 + } else if b { + 1 + } else { + 0 + }; + + // Shouldn't lint + + if a { + 1 + } else if b { + 0 + } else { + 3 + }; + + if a { + 3 + } else if b { + 1 + } else { + -2 + }; + + if a { + 3 + } else { + 0 + }; + if a { + side_effect(); + 1 + } else { + 0 + }; + if a { + 1 + } else { + side_effect(); + 0 + }; + + // multiple else ifs + if a { + 123 + } else if b { + 1 + } else if a | b { + 0 + } else { + 123 + }; + + some_fn(a); +} + +// Lint returns and type inference +fn some_fn(a: bool) -> u8 { + if a { 1 } else { 0 } +} + +fn side_effect() {} + +fn cond(a: bool, b: bool) -> bool { + a || b +} diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr new file mode 100644 index 000000000..8647a9cff --- /dev/null +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr @@ -0,0 +1,84 @@ +error: boolean to int conversion using if + --> $DIR/bool_to_int_with_if.rs:15:5 + | +LL | / if a { +LL | | 1 +LL | | } else { +LL | | 0 +LL | | }; + | |_____^ help: replace with from: `i32::from(a)` + | + = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings` + = note: `a as i32` or `a.into()` can also be valid options + +error: boolean to int conversion using if + --> $DIR/bool_to_int_with_if.rs:20:5 + | +LL | / if !a { +LL | | 1 +LL | | } else { +LL | | 0 +LL | | }; + | |_____^ help: replace with from: `i32::from(!a)` + | + = note: `!a as i32` or `!a.into()` can also be valid options + +error: boolean to int conversion using if + --> $DIR/bool_to_int_with_if.rs:25:5 + | +LL | / if a || b { +LL | | 1 +LL | | } else { +LL | | 0 +LL | | }; + | |_____^ help: replace with from: `i32::from(a || b)` + | + = note: `(a || b) as i32` or `(a || b).into()` can also be valid options + +error: boolean to int conversion using if + --> $DIR/bool_to_int_with_if.rs:30:5 + | +LL | / if cond(a, b) { +LL | | 1 +LL | | } else { +LL | | 0 +LL | | }; + | |_____^ help: replace with from: `i32::from(cond(a, b))` + | + = note: `cond(a, b) as i32` or `cond(a, b).into()` can also be valid options + +error: boolean to int conversion using if + --> $DIR/bool_to_int_with_if.rs:35:5 + | +LL | / if x + y < 4 { +LL | | 1 +LL | | } else { +LL | | 0 +LL | | }; + | |_____^ help: replace with from: `i32::from(x + y < 4)` + | + = note: `(x + y < 4) as i32` or `(x + y < 4).into()` can also be valid options + +error: boolean to int conversion using if + --> $DIR/bool_to_int_with_if.rs:44:12 + | +LL | } else if b { + | ____________^ +LL | | 1 +LL | | } else { +LL | | 0 +LL | | }; + | |_____^ help: replace with from: `{i32::from(b)}` + | + = note: `b as i32` or `b.into()` can also be valid options + +error: boolean to int conversion using if + --> $DIR/bool_to_int_with_if.rs:102:5 + | +LL | if a { 1 } else { 0 } + | ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)` + | + = note: `a as u8` or `a.into()` can also be valid options + +error: aborting due to 7 previous errors + diff --git a/src/tools/clippy/tests/ui/borrow_box.rs b/src/tools/clippy/tests/ui/borrow_box.rs index b606f773c..35ed87b0f 100644 --- a/src/tools/clippy/tests/ui/borrow_box.rs +++ b/src/tools/clippy/tests/ui/borrow_box.rs @@ -1,5 +1,5 @@ #![deny(clippy::borrowed_box)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] #![allow(unused_variables)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/box_collection.rs b/src/tools/clippy/tests/ui/box_collection.rs index 1a74cdb3f..0780c8f05 100644 --- a/src/tools/clippy/tests/ui/box_collection.rs +++ b/src/tools/clippy/tests/ui/box_collection.rs @@ -2,7 +2,7 @@ #![allow( clippy::boxed_local, clippy::needless_pass_by_value, - clippy::blacklisted_name, + clippy::disallowed_names, unused )] diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs index 0d65071af..6f0485b52 100644 --- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs +++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs @@ -14,31 +14,31 @@ fn is_rust_file(filename: &str) -> bool { fn main() { // std::string::String and &str should trigger the lint failure with .ext12 - let _ = String::from("").ends_with(".ext12"); + let _ = String::new().ends_with(".ext12"); let _ = "str".ends_with(".ext12"); // The test struct should not trigger the lint failure with .ext12 TestStruct {}.ends_with(".ext12"); // std::string::String and &str should trigger the lint failure with .EXT12 - let _ = String::from("").ends_with(".EXT12"); + let _ = String::new().ends_with(".EXT12"); let _ = "str".ends_with(".EXT12"); // The test struct should not trigger the lint failure with .EXT12 TestStruct {}.ends_with(".EXT12"); // Should not trigger the lint failure with .eXT12 - let _ = String::from("").ends_with(".eXT12"); + let _ = String::new().ends_with(".eXT12"); let _ = "str".ends_with(".eXT12"); TestStruct {}.ends_with(".eXT12"); // Should not trigger the lint failure with .EXT123 (too long) - let _ = String::from("").ends_with(".EXT123"); + let _ = String::new().ends_with(".EXT123"); let _ = "str".ends_with(".EXT123"); TestStruct {}.ends_with(".EXT123"); // Shouldn't fail if it doesn't start with a dot - let _ = String::from("").ends_with("a.ext"); + let _ = String::new().ends_with("a.ext"); let _ = "str".ends_with("a.extA"); TestStruct {}.ends_with("a.ext"); } diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr index 05b98169f..5d9a043ed 100644 --- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr +++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr @@ -8,10 +8,10 @@ LL | filename.ends_with(".rs") = help: consider using a case-insensitive comparison instead error: case-sensitive file extension comparison - --> $DIR/case_sensitive_file_extension_comparisons.rs:17:30 + --> $DIR/case_sensitive_file_extension_comparisons.rs:17:27 | -LL | let _ = String::from("").ends_with(".ext12"); - | ^^^^^^^^^^^^^^^^^^^ +LL | let _ = String::new().ends_with(".ext12"); + | ^^^^^^^^^^^^^^^^^^^ | = help: consider using a case-insensitive comparison instead @@ -24,10 +24,10 @@ LL | let _ = "str".ends_with(".ext12"); = help: consider using a case-insensitive comparison instead error: case-sensitive file extension comparison - --> $DIR/case_sensitive_file_extension_comparisons.rs:24:30 + --> $DIR/case_sensitive_file_extension_comparisons.rs:24:27 | -LL | let _ = String::from("").ends_with(".EXT12"); - | ^^^^^^^^^^^^^^^^^^^ +LL | let _ = String::new().ends_with(".EXT12"); + | ^^^^^^^^^^^^^^^^^^^ | = help: consider using a case-insensitive comparison instead diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed index a68b32b09..7ecefd7b1 100644 --- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed +++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed @@ -26,4 +26,6 @@ fn main() { let _ = a.unsigned_abs() as u32; let _ = a.unsigned_abs() as u64; let _ = a.unsigned_abs() as u128; + + let _ = (x as i64 - y as i64).unsigned_abs() as u32; } diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs index 110fbc6c2..30c603fca 100644 --- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs +++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs @@ -26,4 +26,6 @@ fn main() { let _ = a.abs() as u32; let _ = a.abs() as u64; let _ = a.abs() as u128; + + let _ = (x as i64 - y as i64).abs() as u32; } diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr index 02c24e106..045537745 100644 --- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr +++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr @@ -96,5 +96,11 @@ error: casting the result of `isize::abs()` to u128 LL | let _ = a.abs() as u128; | ^^^^^^^ help: replace with: `a.unsigned_abs()` -error: aborting due to 16 previous errors +error: casting the result of `i64::abs()` to u32 + --> $DIR/cast_abs_to_unsigned.rs:30:13 + | +LL | let _ = (x as i64 - y as i64).abs() as u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(x as i64 - y as i64).unsigned_abs()` + +error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed new file mode 100644 index 000000000..b70c19129 --- /dev/null +++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed @@ -0,0 +1,24 @@ +// run-rustfix +#![warn(clippy::cast_slice_from_raw_parts)] + +#[allow(unused_imports, unused_unsafe)] +fn main() { + let mut vec = vec![0u8; 1]; + let ptr: *const u8 = vec.as_ptr(); + let mptr = vec.as_mut_ptr(); + let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) }; + let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) }; + let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + { + use core::slice; + let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + use slice as one; + let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + } + { + use std::slice; + let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + use slice as one; + let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + } +} diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs new file mode 100644 index 000000000..c1b316765 --- /dev/null +++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs @@ -0,0 +1,24 @@ +// run-rustfix +#![warn(clippy::cast_slice_from_raw_parts)] + +#[allow(unused_imports, unused_unsafe)] +fn main() { + let mut vec = vec![0u8; 1]; + let ptr: *const u8 = vec.as_ptr(); + let mptr = vec.as_mut_ptr(); + let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] }; + let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] }; + let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8]; + { + use core::slice; + let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; + use slice as one; + let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; + } + { + use std::slice; + let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; + use slice as one; + let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; + } +} diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr new file mode 100644 index 000000000..f07801c19 --- /dev/null +++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr @@ -0,0 +1,46 @@ +error: casting the result of `from_raw_parts` to *const [u8] + --> $DIR/cast_raw_slice_pointer_cast.rs:9:35 + | +LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` + | + = note: `-D clippy::cast-slice-from-raw-parts` implied by `-D warnings` + +error: casting the result of `from_raw_parts_mut` to *mut [u8] + --> $DIR/cast_raw_slice_pointer_cast.rs:10:35 + | +LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)` + +error: casting the result of `from_raw_parts` to *const [u8] + --> $DIR/cast_raw_slice_pointer_cast.rs:11:26 + | +LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` + +error: casting the result of `from_raw_parts` to *const [u8] + --> $DIR/cast_raw_slice_pointer_cast.rs:14:30 + | +LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` + +error: casting the result of `from_raw_parts` to *const [u8] + --> $DIR/cast_raw_slice_pointer_cast.rs:16:30 + | +LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` + +error: casting the result of `from_raw_parts` to *const [u8] + --> $DIR/cast_raw_slice_pointer_cast.rs:20:30 + | +LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` + +error: casting the result of `from_raw_parts` to *const [u8] + --> $DIR/cast_raw_slice_pointer_cast.rs:22:30 + | +LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` + +error: aborting due to 7 previous errors + diff --git a/src/tools/clippy/tests/ui/clone_on_copy.fixed b/src/tools/clippy/tests/ui/clone_on_copy.fixed index dc0627626..72b122270 100644 --- a/src/tools/clippy/tests/ui/clone_on_copy.fixed +++ b/src/tools/clippy/tests/ui/clone_on_copy.fixed @@ -21,7 +21,7 @@ fn is_ascii(ch: char) -> bool { ch.is_ascii() } -fn clone_on_copy() { +fn clone_on_copy() -> Option<(i32)> { 42; vec![1].clone(); // ok, not a Copy type @@ -71,4 +71,9 @@ fn clone_on_copy() { // Issue #5436 let mut vec = Vec::new(); vec.push(42); + + // Issue #9277 + let opt: &Option<i32> = &None; + let value = (*opt)?; // operator precedence needed (*opt)? + None } diff --git a/src/tools/clippy/tests/ui/clone_on_copy.rs b/src/tools/clippy/tests/ui/clone_on_copy.rs index 8c39d0d55..03e210eba 100644 --- a/src/tools/clippy/tests/ui/clone_on_copy.rs +++ b/src/tools/clippy/tests/ui/clone_on_copy.rs @@ -21,7 +21,7 @@ fn is_ascii(ch: char) -> bool { ch.is_ascii() } -fn clone_on_copy() { +fn clone_on_copy() -> Option<(i32)> { 42.clone(); vec![1].clone(); // ok, not a Copy type @@ -71,4 +71,9 @@ fn clone_on_copy() { // Issue #5436 let mut vec = Vec::new(); vec.push(42.clone()); + + // Issue #9277 + let opt: &Option<i32> = &None; + let value = opt.clone()?; // operator precedence needed (*opt)? + None } diff --git a/src/tools/clippy/tests/ui/clone_on_copy.stderr b/src/tools/clippy/tests/ui/clone_on_copy.stderr index 861543d0a..42ae22777 100644 --- a/src/tools/clippy/tests/ui/clone_on_copy.stderr +++ b/src/tools/clippy/tests/ui/clone_on_copy.stderr @@ -48,5 +48,11 @@ error: using `clone` on type `i32` which implements the `Copy` trait LL | vec.push(42.clone()); | ^^^^^^^^^^ help: try removing the `clone` call: `42` -error: aborting due to 8 previous errors +error: using `clone` on type `std::option::Option<i32>` which implements the `Copy` trait + --> $DIR/clone_on_copy.rs:77:17 + | +LL | let value = opt.clone()?; // operator precedence needed (*opt)? + | ^^^^^^^^^^^ help: try dereferencing it: `(*opt)` + +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.fixed b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed new file mode 100644 index 000000000..49fc9a962 --- /dev/null +++ b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +#![warn(clippy::collapsible_str_replace)] + +fn get_filter() -> char { + 'u' +} + +fn main() { + let d = 'd'; + let p = 'p'; + let s = 's'; + let u = 'u'; + let l = "l"; + + let mut iter = ["l", "z"].iter(); + + // LINT CASES + let _ = "hesuo worpd".replace(['s', 'u'], "l"); + + let _ = "hesuo worpd".replace(['s', 'u'], l); + + let _ = "hesuo worpd".replace(['s', 'u', 'p'], "l"); + + let _ = "hesuo worpd" + .replace(['s', 'u', 'p', 'd'], "l"); + + let _ = "hesuo world".replace([s, 'u'], "l"); + + let _ = "hesuo worpd".replace([s, 'u', 'p'], "l"); + + let _ = "hesuo worpd".replace([s, u, 'p'], "l"); + + let _ = "hesuo worpd".replace([s, u, p], "l"); + + let _ = "hesuo worlp".replace(['s', 'u'], "l").replace('p', "d"); + + let _ = "hesuo worpd".replace('s', "x").replace(['u', 'p'], "l"); + + // Note: Future iterations could lint `replace(|c| matches!(c, "su" | 'd' | 'p'), "l")` + let _ = "hesudo worpd".replace("su", "l").replace(['d', 'p'], "l"); + + let _ = "hesudo worpd".replace([d, 'p'], "l").replace("su", "l"); + + let _ = "hesuo world".replace([get_filter(), 's'], "l"); + + // NO LINT CASES + let _ = "hesuo world".replace('s', "l").replace('u', "p"); + + let _ = "hesuo worpd".replace('s', "l").replace('p', l); + + let _ = "hesudo worpd".replace('d', "l").replace("su", "l").replace('p', "l"); + + // Note: Future iterations of `collapsible_str_replace` might lint this and combine to `[s, u, p]` + let _ = "hesuo worpd".replace([s, u], "l").replace([u, p], "l"); + + let _ = "hesuo worpd".replace(['s', 'u'], "l").replace(['u', 'p'], "l"); + + let _ = "hesuo worpd".replace('s', "l").replace(['u', 'p'], "l"); + + let _ = "hesuo worpd".replace(['s', 'u', 'p'], "l").replace('r', "l"); + + let _ = "hesuo worpd".replace(['s', 'u', 'p'], l).replace('r', l); + + let _ = "hesuo worpd".replace(['s', u, 'p'], "l").replace('r', "l"); + + let _ = "hesuo worpd".replace([s, u], "l").replace(p, "l"); + + // Regression test + let _ = "hesuo worpd" + .replace('u', iter.next().unwrap()) + .replace('s', iter.next().unwrap()); +} diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.rs b/src/tools/clippy/tests/ui/collapsible_str_replace.rs new file mode 100644 index 000000000..e3e25c414 --- /dev/null +++ b/src/tools/clippy/tests/ui/collapsible_str_replace.rs @@ -0,0 +1,76 @@ +// run-rustfix + +#![warn(clippy::collapsible_str_replace)] + +fn get_filter() -> char { + 'u' +} + +fn main() { + let d = 'd'; + let p = 'p'; + let s = 's'; + let u = 'u'; + let l = "l"; + + let mut iter = ["l", "z"].iter(); + + // LINT CASES + let _ = "hesuo worpd".replace('s', "l").replace('u', "l"); + + let _ = "hesuo worpd".replace('s', l).replace('u', l); + + let _ = "hesuo worpd".replace('s', "l").replace('u', "l").replace('p', "l"); + + let _ = "hesuo worpd" + .replace('s', "l") + .replace('u', "l") + .replace('p', "l") + .replace('d', "l"); + + let _ = "hesuo world".replace(s, "l").replace('u', "l"); + + let _ = "hesuo worpd".replace(s, "l").replace('u', "l").replace('p', "l"); + + let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace('p', "l"); + + let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace(p, "l"); + + let _ = "hesuo worlp".replace('s', "l").replace('u', "l").replace('p', "d"); + + let _ = "hesuo worpd".replace('s', "x").replace('u', "l").replace('p', "l"); + + // Note: Future iterations could lint `replace(|c| matches!(c, "su" | 'd' | 'p'), "l")` + let _ = "hesudo worpd".replace("su", "l").replace('d', "l").replace('p', "l"); + + let _ = "hesudo worpd".replace(d, "l").replace('p', "l").replace("su", "l"); + + let _ = "hesuo world".replace(get_filter(), "l").replace('s', "l"); + + // NO LINT CASES + let _ = "hesuo world".replace('s', "l").replace('u', "p"); + + let _ = "hesuo worpd".replace('s', "l").replace('p', l); + + let _ = "hesudo worpd".replace('d', "l").replace("su", "l").replace('p', "l"); + + // Note: Future iterations of `collapsible_str_replace` might lint this and combine to `[s, u, p]` + let _ = "hesuo worpd".replace([s, u], "l").replace([u, p], "l"); + + let _ = "hesuo worpd".replace(['s', 'u'], "l").replace(['u', 'p'], "l"); + + let _ = "hesuo worpd".replace('s', "l").replace(['u', 'p'], "l"); + + let _ = "hesuo worpd".replace(['s', 'u', 'p'], "l").replace('r', "l"); + + let _ = "hesuo worpd".replace(['s', 'u', 'p'], l).replace('r', l); + + let _ = "hesuo worpd".replace(['s', u, 'p'], "l").replace('r', "l"); + + let _ = "hesuo worpd".replace([s, u], "l").replace(p, "l"); + + // Regression test + let _ = "hesuo worpd" + .replace('u', iter.next().unwrap()) + .replace('s', iter.next().unwrap()); +} diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.stderr b/src/tools/clippy/tests/ui/collapsible_str_replace.stderr new file mode 100644 index 000000000..8e3daf3b8 --- /dev/null +++ b/src/tools/clippy/tests/ui/collapsible_str_replace.stderr @@ -0,0 +1,86 @@ +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:19:27 + | +LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], "l")` + | + = note: `-D clippy::collapsible-str-replace` implied by `-D warnings` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:21:27 + | +LL | let _ = "hesuo worpd".replace('s', l).replace('u', l); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], l)` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:23:27 + | +LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l").replace('p', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u', 'p'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:26:10 + | +LL | .replace('s', "l") + | __________^ +LL | | .replace('u', "l") +LL | | .replace('p', "l") +LL | | .replace('d', "l"); + | |__________________________^ help: replace with: `replace(['s', 'u', 'p', 'd'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:31:27 + | +LL | let _ = "hesuo world".replace(s, "l").replace('u', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:33:27 + | +LL | let _ = "hesuo worpd".replace(s, "l").replace('u', "l").replace('p', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u', 'p'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:35:27 + | +LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace('p', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, 'p'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:37:27 + | +LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace(p, "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, p], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:39:27 + | +LL | let _ = "hesuo worlp".replace('s', "l").replace('u', "l").replace('p', "d"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:41:45 + | +LL | let _ = "hesuo worpd".replace('s', "x").replace('u', "l").replace('p', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['u', 'p'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:44:47 + | +LL | let _ = "hesudo worpd".replace("su", "l").replace('d', "l").replace('p', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['d', 'p'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:46:28 + | +LL | let _ = "hesudo worpd".replace(d, "l").replace('p', "l").replace("su", "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([d, 'p'], "l")` + +error: used consecutive `str::replace` call + --> $DIR/collapsible_str_replace.rs:48:27 + | +LL | let _ = "hesuo world".replace(get_filter(), "l").replace('s', "l"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([get_filter(), 's'], "l")` + +error: aborting due to 13 previous errors + diff --git a/src/tools/clippy/tests/ui/crashes/ice-2760.rs b/src/tools/clippy/tests/ui/crashes/ice-2760.rs index f1a229f3f..61ef24804 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-2760.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-2760.rs @@ -1,6 +1,6 @@ #![allow( unused_variables, - clippy::blacklisted_name, + clippy::disallowed_names, clippy::needless_pass_by_value, dead_code )] diff --git a/src/tools/clippy/tests/ui/crashes/ice-3462.rs b/src/tools/clippy/tests/ui/crashes/ice-3462.rs index 02c49aa0d..b40205288 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-3462.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-3462.rs @@ -1,5 +1,5 @@ #![warn(clippy::all)] -#![allow(clippy::blacklisted_name, clippy::equatable_if_let)] +#![allow(clippy::disallowed_names, clippy::equatable_if_let)] #![allow(unused)] /// Test for https://github.com/rust-lang/rust-clippy/issues/3462 diff --git a/src/tools/clippy/tests/ui/crashes/ice-9405.rs b/src/tools/clippy/tests/ui/crashes/ice-9405.rs new file mode 100644 index 000000000..e2d274aeb --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-9405.rs @@ -0,0 +1,11 @@ +#![warn(clippy::useless_format)] +#![allow(clippy::print_literal)] + +fn main() { + println!( + "\ + + {}", + "multiple skipped lines" + ); +} diff --git a/src/tools/clippy/tests/ui/crashes/ice-9405.stderr b/src/tools/clippy/tests/ui/crashes/ice-9405.stderr new file mode 100644 index 000000000..9a6e410f2 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-9405.stderr @@ -0,0 +1,11 @@ +warning: multiple lines skipped by escaped newline + --> $DIR/ice-9405.rs:6:10 + | +LL | "/ + | __________^ +LL | | +LL | | {}", + | |____________^ skipping everything up to and including this point + +warning: 1 warning emitted + diff --git a/src/tools/clippy/tests/ui/crashes/ice-9414.rs b/src/tools/clippy/tests/ui/crashes/ice-9414.rs new file mode 100644 index 000000000..02cf5d5c2 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-9414.rs @@ -0,0 +1,8 @@ +#![warn(clippy::result_large_err)] + +trait T {} +fn f(_: &u32) -> Result<(), *const (dyn '_ + T)> { + Ok(()) +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/regressions.rs b/src/tools/clippy/tests/ui/crashes/regressions.rs index 6f9d98bbf..55a8b4034 100644 --- a/src/tools/clippy/tests/ui/crashes/regressions.rs +++ b/src/tools/clippy/tests/ui/crashes/regressions.rs @@ -1,4 +1,4 @@ -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] pub fn foo(bar: *const u8) { println!("{:#p}", bar); diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs index 156c88e2e..a7da8f89a 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.rs +++ b/src/tools/clippy/tests/ui/def_id_nocore.rs @@ -1,4 +1,3 @@ -// ignore-windows // ignore-macos #![feature(no_core, lang_items, start)] diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr index 40d355e9a..6210d7c6c 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.stderr +++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr @@ -1,5 +1,5 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> $DIR/def_id_nocore.rs:28:19 + --> $DIR/def_id_nocore.rs:27:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ diff --git a/src/tools/clippy/tests/ui/default_trait_access.fixed b/src/tools/clippy/tests/ui/default_trait_access.fixed index 264dd4efa..fce66eb17 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.fixed +++ b/src/tools/clippy/tests/ui/default_trait_access.fixed @@ -1,8 +1,12 @@ // run-rustfix +// aux-build: proc_macro_with_span.rs #![allow(unused_imports, dead_code)] #![deny(clippy::default_trait_access)] +extern crate proc_macro_with_span; + +use proc_macro_with_span::with_span; use std::default; use std::default::Default as D2; use std::string; @@ -51,6 +55,8 @@ fn main() { ..Default::default() }; + let _s21: String = with_span!(s Default::default()); + println!( "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}]", s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, diff --git a/src/tools/clippy/tests/ui/default_trait_access.rs b/src/tools/clippy/tests/ui/default_trait_access.rs index a0930fab8..3e8e898b7 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.rs +++ b/src/tools/clippy/tests/ui/default_trait_access.rs @@ -1,8 +1,12 @@ // run-rustfix +// aux-build: proc_macro_with_span.rs #![allow(unused_imports, dead_code)] #![deny(clippy::default_trait_access)] +extern crate proc_macro_with_span; + +use proc_macro_with_span::with_span; use std::default; use std::default::Default as D2; use std::string; @@ -51,6 +55,8 @@ fn main() { ..Default::default() }; + let _s21: String = with_span!(s Default::default()); + println!( "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}]", s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, diff --git a/src/tools/clippy/tests/ui/default_trait_access.stderr b/src/tools/clippy/tests/ui/default_trait_access.stderr index df8a5b94d..3493de37a 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.stderr +++ b/src/tools/clippy/tests/ui/default_trait_access.stderr @@ -1,53 +1,53 @@ error: calling `std::string::String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:11:22 + --> $DIR/default_trait_access.rs:15:22 | LL | let s1: String = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()` | note: the lint level is defined here - --> $DIR/default_trait_access.rs:4:9 + --> $DIR/default_trait_access.rs:5:9 | LL | #![deny(clippy::default_trait_access)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: calling `std::string::String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:15:22 + --> $DIR/default_trait_access.rs:19:22 | LL | let s3: String = D2::default(); | ^^^^^^^^^^^^^ help: try: `std::string::String::default()` error: calling `std::string::String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:17:22 + --> $DIR/default_trait_access.rs:21:22 | LL | let s4: String = std::default::Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()` error: calling `std::string::String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:21:22 + --> $DIR/default_trait_access.rs:25:22 | LL | let s6: String = default::Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()` error: calling `GenericDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:31:46 + --> $DIR/default_trait_access.rs:35:46 | LL | let s11: GenericDerivedDefault<String> = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()` error: calling `TupleDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:37:36 + --> $DIR/default_trait_access.rs:41:36 | LL | let s14: TupleDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()` error: calling `ArrayDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:39:36 + --> $DIR/default_trait_access.rs:43:36 | LL | let s15: ArrayDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()` error: calling `TupleStructDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:43:42 + --> $DIR/default_trait_access.rs:47:42 | LL | let s17: TupleStructDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()` diff --git a/src/tools/clippy/tests/ui/blacklisted_name.rs b/src/tools/clippy/tests/ui/disallowed_names.rs index 27df732a0..e937c49f3 100644 --- a/src/tools/clippy/tests/ui/blacklisted_name.rs +++ b/src/tools/clippy/tests/ui/disallowed_names.rs @@ -6,7 +6,7 @@ unused_mut, unused_variables )] -#![warn(clippy::blacklisted_name)] +#![warn(clippy::disallowed_names)] fn test(foo: ()) {} @@ -46,7 +46,7 @@ fn issue_1647_ref_mut() { mod tests { fn issue_7305() { - // `blacklisted_name` lint should not be triggered inside of the test code. + // `disallowed_names` lint should not be triggered inside of the test code. let foo = 0; // Check that even in nested functions warning is still not triggered. diff --git a/src/tools/clippy/tests/ui/disallowed_names.stderr b/src/tools/clippy/tests/ui/disallowed_names.stderr new file mode 100644 index 000000000..78cb55096 --- /dev/null +++ b/src/tools/clippy/tests/ui/disallowed_names.stderr @@ -0,0 +1,88 @@ +error: use of a disallowed/placeholder name `foo` + --> $DIR/disallowed_names.rs:11:9 + | +LL | fn test(foo: ()) {} + | ^^^ + | + = note: `-D clippy::disallowed-names` implied by `-D warnings` + +error: use of a disallowed/placeholder name `foo` + --> $DIR/disallowed_names.rs:14:9 + | +LL | let foo = 42; + | ^^^ + +error: use of a disallowed/placeholder name `baz` + --> $DIR/disallowed_names.rs:15:9 + | +LL | let baz = 42; + | ^^^ + +error: use of a disallowed/placeholder name `quux` + --> $DIR/disallowed_names.rs:16:9 + | +LL | let quux = 42; + | ^^^^ + +error: use of a disallowed/placeholder name `foo` + --> $DIR/disallowed_names.rs:27:10 + | +LL | (foo, Some(baz), quux @ Some(_)) => (), + | ^^^ + +error: use of a disallowed/placeholder name `baz` + --> $DIR/disallowed_names.rs:27:20 + | +LL | (foo, Some(baz), quux @ Some(_)) => (), + | ^^^ + +error: use of a disallowed/placeholder name `quux` + --> $DIR/disallowed_names.rs:27:26 + | +LL | (foo, Some(baz), quux @ Some(_)) => (), + | ^^^^ + +error: use of a disallowed/placeholder name `foo` + --> $DIR/disallowed_names.rs:32:19 + | +LL | fn issue_1647(mut foo: u8) { + | ^^^ + +error: use of a disallowed/placeholder name `baz` + --> $DIR/disallowed_names.rs:33:13 + | +LL | let mut baz = 0; + | ^^^ + +error: use of a disallowed/placeholder name `quux` + --> $DIR/disallowed_names.rs:34:21 + | +LL | if let Some(mut quux) = Some(42) {} + | ^^^^ + +error: use of a disallowed/placeholder name `baz` + --> $DIR/disallowed_names.rs:38:13 + | +LL | let ref baz = 0; + | ^^^ + +error: use of a disallowed/placeholder name `quux` + --> $DIR/disallowed_names.rs:39:21 + | +LL | if let Some(ref quux) = Some(42) {} + | ^^^^ + +error: use of a disallowed/placeholder name `baz` + --> $DIR/disallowed_names.rs:43:17 + | +LL | let ref mut baz = 0; + | ^^^ + +error: use of a disallowed/placeholder name `quux` + --> $DIR/disallowed_names.rs:44:25 + | +LL | if let Some(ref mut quux) = Some(42) {} + | ^^^^ + +error: aborting due to 14 previous errors + diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.rs b/src/tools/clippy/tests/ui/diverging_sub_expression.rs index e27f9fea7..e8f992e6d 100644 --- a/src/tools/clippy/tests/ui/diverging_sub_expression.rs +++ b/src/tools/clippy/tests/ui/diverging_sub_expression.rs @@ -1,5 +1,5 @@ #![warn(clippy::diverging_sub_expression)] -#![allow(clippy::match_same_arms, clippy::logic_bug)] +#![allow(clippy::match_same_arms, clippy::overly_complex_bool_expr)] #[allow(clippy::empty_loop)] fn diverge() -> ! { loop {} diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.rs b/src/tools/clippy/tests/ui/empty_loop_no_std.rs index 235e0fc51..e742b396f 100644 --- a/src/tools/clippy/tests/ui/empty_loop_no_std.rs +++ b/src/tools/clippy/tests/ui/empty_loop_no_std.rs @@ -1,6 +1,5 @@ // compile-flags: -Clink-arg=-nostartfiles // ignore-macos -// ignore-windows #![warn(clippy::empty_loop)] #![feature(lang_items, start, libc)] diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr index 520248fcb..5ded35a6f 100644 --- a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr +++ b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr @@ -1,5 +1,5 @@ error: empty `loop {}` wastes CPU cycles - --> $DIR/empty_loop_no_std.rs:14:5 + --> $DIR/empty_loop_no_std.rs:13:5 | LL | loop {} | ^^^^^^^ @@ -8,7 +8,7 @@ LL | loop {} = help: you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body error: empty `loop {}` wastes CPU cycles - --> $DIR/empty_loop_no_std.rs:26:5 + --> $DIR/empty_loop_no_std.rs:25:5 | LL | loop {} | ^^^^^^^ diff --git a/src/tools/clippy/tests/ui/expect.rs b/src/tools/clippy/tests/ui/expect.rs index 1073acf6f..d742595e1 100644 --- a/src/tools/clippy/tests/ui/expect.rs +++ b/src/tools/clippy/tests/ui/expect.rs @@ -6,8 +6,9 @@ fn expect_option() { } fn expect_result() { - let res: Result<u8, ()> = Ok(0); + let res: Result<u8, u8> = Ok(0); let _ = res.expect(""); + let _ = res.expect_err(""); } fn main() { diff --git a/src/tools/clippy/tests/ui/expect.stderr b/src/tools/clippy/tests/ui/expect.stderr index 9d3fc7df1..904c09046 100644 --- a/src/tools/clippy/tests/ui/expect.stderr +++ b/src/tools/clippy/tests/ui/expect.stderr @@ -5,7 +5,7 @@ LL | let _ = opt.expect(""); | ^^^^^^^^^^^^^^ | = note: `-D clippy::expect-used` implied by `-D warnings` - = help: if this value is an `None`, it will panic + = help: if this value is `None`, it will panic error: used `expect()` on `a Result` value --> $DIR/expect.rs:10:13 @@ -15,5 +15,13 @@ LL | let _ = res.expect(""); | = help: if this value is an `Err`, it will panic -error: aborting due to 2 previous errors +error: used `expect_err()` on `a Result` value + --> $DIR/expect.rs:11:13 + | +LL | let _ = res.expect_err(""); + | ^^^^^^^^^^^^^^^^^^ + | + = help: if this value is an `Ok`, it will panic + +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs index 28b37f96e..0415e33b3 100644 --- a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs +++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs @@ -98,7 +98,7 @@ mod clippy_ok { let _ = if true { 42 } else { 42 }; } - #[expect(clippy::logic_bug)] + #[expect(clippy::overly_complex_bool_expr)] fn burger() { let a = false; let b = true; @@ -127,7 +127,7 @@ mod clippy_warn { let _ = if true { 33 } else { 42 }; } - #[expect(clippy::logic_bug)] + #[expect(clippy::overly_complex_bool_expr)] fn burger() { let a = false; let b = true; diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr index db29e85a8..7ce9e855b 100644 --- a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr +++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr @@ -33,8 +33,8 @@ LL | #[expect(clippy::if_same_then_else)] error: this lint expectation is unfulfilled --> $DIR/expect_tool_lint_rfc_2383.rs:130:14 | -LL | #[expect(clippy::logic_bug)] - | ^^^^^^^^^^^^^^^^^ +LL | #[expect(clippy::overly_complex_bool_expr)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed index a650fdc1f..d1d35e5c0 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed @@ -1,5 +1,6 @@ // run-rustfix +#![feature(closure_lifetime_binder)] #![warn(clippy::explicit_auto_deref)] #![allow( dead_code, @@ -67,6 +68,8 @@ fn main() { let s = String::new(); let _: &str = &s; + let _: &str = &{ String::new() }; + let _: &str = &mut { String::new() }; let _ = &*s; // Don't lint. Inferred type would change. let _: &_ = &*s; // Don't lint. Inferred type would change. @@ -215,4 +218,52 @@ fn main() { let s = &"str"; let _ = || return *s; let _ = || -> &'static str { return s }; + + struct X; + struct Y(X); + impl core::ops::Deref for Y { + type Target = X; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + let _: &X = &*{ Y(X) }; + let _: &X = &*match 0 { + #[rustfmt::skip] + 0 => { Y(X) }, + _ => panic!(), + }; + let _: &X = &*if true { Y(X) } else { panic!() }; + + fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U { + x + } + + let _ = |x: &'static Box<dyn Iterator<Item = u32>>| -> &'static dyn Iterator<Item = u32> { &**x }; + fn ret_any(x: &Box<dyn std::any::Any>) -> &dyn std::any::Any { + &**x + } + + let x = String::new(); + let _: *const str = &*x; + + struct S7([u32; 1]); + impl core::ops::Deref for S7 { + type Target = [u32; 1]; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + let x = S7([0]); + let _: &[u32] = &*x; + + let c1 = |_: &Vec<&u32>| {}; + let x = &&vec![&1u32]; + c1(x); + let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> { + if b { + return x; + } + x + }; } diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs index 8f4f35257..deedafad1 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs @@ -1,5 +1,6 @@ // run-rustfix +#![feature(closure_lifetime_binder)] #![warn(clippy::explicit_auto_deref)] #![allow( dead_code, @@ -67,6 +68,8 @@ fn main() { let s = String::new(); let _: &str = &*s; + let _: &str = &*{ String::new() }; + let _: &str = &mut *{ String::new() }; let _ = &*s; // Don't lint. Inferred type would change. let _: &_ = &*s; // Don't lint. Inferred type would change. @@ -215,4 +218,52 @@ fn main() { let s = &"str"; let _ = || return *s; let _ = || -> &'static str { return *s }; + + struct X; + struct Y(X); + impl core::ops::Deref for Y { + type Target = X; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + let _: &X = &*{ Y(X) }; + let _: &X = &*match 0 { + #[rustfmt::skip] + 0 => { Y(X) }, + _ => panic!(), + }; + let _: &X = &*if true { Y(X) } else { panic!() }; + + fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U { + &**x + } + + let _ = |x: &'static Box<dyn Iterator<Item = u32>>| -> &'static dyn Iterator<Item = u32> { &**x }; + fn ret_any(x: &Box<dyn std::any::Any>) -> &dyn std::any::Any { + &**x + } + + let x = String::new(); + let _: *const str = &*x; + + struct S7([u32; 1]); + impl core::ops::Deref for S7 { + type Target = [u32; 1]; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + let x = S7([0]); + let _: &[u32] = &*x; + + let c1 = |_: &Vec<&u32>| {}; + let x = &&vec![&1u32]; + c1(*x); + let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> { + if b { + return *x; + } + *x + }; } diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr index 92765307e..91863abcc 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr @@ -1,202 +1,238 @@ error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:69:20 + --> $DIR/explicit_auto_deref.rs:70:19 | LL | let _: &str = &*s; - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` | = note: `-D clippy::explicit-auto-deref` implied by `-D warnings` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:73:12 + --> $DIR/explicit_auto_deref.rs:71:19 + | +LL | let _: &str = &*{ String::new() }; + | ^^^^^^^^^^^^^^^^^^^ help: try this: `&{ String::new() }` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:72:19 + | +LL | let _: &str = &mut *{ String::new() }; + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut { String::new() }` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:76:11 | LL | f_str(&*s); - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:77:14 + --> $DIR/explicit_auto_deref.rs:80:13 | LL | f_str_t(&*s, &*s); // Don't lint second param. - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:80:25 + --> $DIR/explicit_auto_deref.rs:83:24 | LL | let _: &Box<i32> = &**b; - | ^^^ help: try this: `b` + | ^^^^ help: try this: `&b` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:86:8 + --> $DIR/explicit_auto_deref.rs:89:7 | LL | c(&*s); - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:92:9 + --> $DIR/explicit_auto_deref.rs:95:9 | LL | &**x | ^^^^ help: try this: `x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:96:11 + --> $DIR/explicit_auto_deref.rs:99:11 | LL | { &**x } | ^^^^ help: try this: `x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:100:9 + --> $DIR/explicit_auto_deref.rs:103:9 | LL | &**{ x } | ^^^^^^^^ help: try this: `{ x }` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:104:9 + --> $DIR/explicit_auto_deref.rs:107:9 | LL | &***x | ^^^^^ help: try this: `x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:121:13 + --> $DIR/explicit_auto_deref.rs:124:12 | LL | f1(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:122:13 + --> $DIR/explicit_auto_deref.rs:125:12 | LL | f2(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:123:13 + --> $DIR/explicit_auto_deref.rs:126:12 | LL | f3(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:124:28 + --> $DIR/explicit_auto_deref.rs:127:27 | LL | f4.callable_str()(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:125:13 + --> $DIR/explicit_auto_deref.rs:128:12 | LL | f5(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:126:13 + --> $DIR/explicit_auto_deref.rs:129:12 | LL | f6(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:127:28 + --> $DIR/explicit_auto_deref.rs:130:27 | LL | f7.callable_str()(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:128:26 + --> $DIR/explicit_auto_deref.rs:131:25 | LL | f8.callable_t()(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:129:13 + --> $DIR/explicit_auto_deref.rs:132:12 | LL | f9(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:130:14 + --> $DIR/explicit_auto_deref.rs:133:13 | LL | f10(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:131:27 + --> $DIR/explicit_auto_deref.rs:134:26 | LL | f11.callable_t()(&*x); - | ^^ help: try this: `x` + | ^^^ help: try this: `&x` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:135:17 + --> $DIR/explicit_auto_deref.rs:138:16 | LL | let _ = S1(&*s); - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:140:22 + --> $DIR/explicit_auto_deref.rs:143:21 | LL | let _ = S2 { s: &*s }; - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:156:30 + --> $DIR/explicit_auto_deref.rs:159:30 | LL | let _ = Self::S1(&**s); | ^^^^ help: try this: `s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:157:35 + --> $DIR/explicit_auto_deref.rs:160:35 | LL | let _ = Self::S2 { s: &**s }; | ^^^^ help: try this: `s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:160:21 + --> $DIR/explicit_auto_deref.rs:163:20 | LL | let _ = E1::S1(&*s); - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:161:26 + --> $DIR/explicit_auto_deref.rs:164:25 | LL | let _ = E1::S2 { s: &*s }; - | ^^ help: try this: `s` + | ^^^ help: try this: `&s` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:179:13 + --> $DIR/explicit_auto_deref.rs:182:13 | LL | let _ = (*b).foo; | ^^^^ help: try this: `b` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:180:13 + --> $DIR/explicit_auto_deref.rs:183:13 | LL | let _ = (**b).foo; | ^^^^^ help: try this: `b` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:195:19 + --> $DIR/explicit_auto_deref.rs:198:19 | LL | let _ = f_str(*ref_str); | ^^^^^^^^ help: try this: `ref_str` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:197:19 + --> $DIR/explicit_auto_deref.rs:200:19 | LL | let _ = f_str(**ref_ref_str); | ^^^^^^^^^^^^^ help: try this: `ref_ref_str` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:207:13 + --> $DIR/explicit_auto_deref.rs:210:13 | LL | f_str(&&*ref_str); // `needless_borrow` will suggest removing both references | ^^^^^^^^ help: try this: `ref_str` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:208:12 + --> $DIR/explicit_auto_deref.rs:211:12 | LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference | ^^^^^^^^^^ help: try this: `ref_str` error: deref which would be done by auto-deref - --> $DIR/explicit_auto_deref.rs:217:41 + --> $DIR/explicit_auto_deref.rs:220:41 | LL | let _ = || -> &'static str { return *s }; | ^^ help: try this: `s` -error: aborting due to 33 previous errors +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:239:9 + | +LL | &**x + | ^^^^ help: try this: `x` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:262:8 + | +LL | c1(*x); + | ^^ help: try this: `x` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:265:20 + | +LL | return *x; + | ^^ help: try this: `x` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:267:9 + | +LL | *x + | ^^ help: try this: `x` + +error: aborting due to 39 previous errors diff --git a/src/tools/clippy/tests/ui/floating_point_exp.fixed b/src/tools/clippy/tests/ui/floating_point_exp.fixed index ae7805fdf..c86a502d1 100644 --- a/src/tools/clippy/tests/ui/floating_point_exp.fixed +++ b/src/tools/clippy/tests/ui/floating_point_exp.fixed @@ -5,6 +5,7 @@ fn main() { let x = 2f32; let _ = x.exp_m1(); let _ = x.exp_m1() + 2.0; + let _ = (x as f32).exp_m1() + 2.0; // Cases where the lint shouldn't be applied let _ = x.exp() - 2.0; let _ = x.exp() - 1.0 * 2.0; diff --git a/src/tools/clippy/tests/ui/floating_point_exp.rs b/src/tools/clippy/tests/ui/floating_point_exp.rs index 27e0b9bcb..e59589f91 100644 --- a/src/tools/clippy/tests/ui/floating_point_exp.rs +++ b/src/tools/clippy/tests/ui/floating_point_exp.rs @@ -5,6 +5,7 @@ fn main() { let x = 2f32; let _ = x.exp() - 1.0; let _ = x.exp() - 1.0 + 2.0; + let _ = (x as f32).exp() - 1.0 + 2.0; // Cases where the lint shouldn't be applied let _ = x.exp() - 2.0; let _ = x.exp() - 1.0 * 2.0; diff --git a/src/tools/clippy/tests/ui/floating_point_exp.stderr b/src/tools/clippy/tests/ui/floating_point_exp.stderr index 5cd999ad4..f84eede19 100644 --- a/src/tools/clippy/tests/ui/floating_point_exp.stderr +++ b/src/tools/clippy/tests/ui/floating_point_exp.stderr @@ -13,16 +13,22 @@ LL | let _ = x.exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> $DIR/floating_point_exp.rs:13:13 + --> $DIR/floating_point_exp.rs:8:13 + | +LL | let _ = (x as f32).exp() - 1.0 + 2.0; + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).exp_m1()` + +error: (e.pow(x) - 1) can be computed more accurately + --> $DIR/floating_point_exp.rs:14:13 | LL | let _ = x.exp() - 1.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> $DIR/floating_point_exp.rs:14:13 + --> $DIR/floating_point_exp.rs:15:13 | LL | let _ = x.exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/floating_point_log.fixed b/src/tools/clippy/tests/ui/floating_point_log.fixed index 5b487bb8f..4def9300b 100644 --- a/src/tools/clippy/tests/ui/floating_point_log.fixed +++ b/src/tools/clippy/tests/ui/floating_point_log.fixed @@ -12,6 +12,7 @@ fn check_log_base() { let _ = x.ln(); let _ = x.log2(); let _ = x.ln(); + let _ = (x as f32).log2(); let x = 1f64; let _ = x.log2(); diff --git a/src/tools/clippy/tests/ui/floating_point_log.rs b/src/tools/clippy/tests/ui/floating_point_log.rs index 01181484e..1e04caa7d 100644 --- a/src/tools/clippy/tests/ui/floating_point_log.rs +++ b/src/tools/clippy/tests/ui/floating_point_log.rs @@ -12,6 +12,7 @@ fn check_log_base() { let _ = x.log(std::f32::consts::E); let _ = x.log(TWO); let _ = x.log(E); + let _ = (x as f32).log(2f32); let x = 1f64; let _ = x.log(2f64); diff --git a/src/tools/clippy/tests/ui/floating_point_log.stderr b/src/tools/clippy/tests/ui/floating_point_log.stderr index 96e5a1544..89800a13a 100644 --- a/src/tools/clippy/tests/ui/floating_point_log.stderr +++ b/src/tools/clippy/tests/ui/floating_point_log.stderr @@ -31,25 +31,31 @@ LL | let _ = x.log(E); | ^^^^^^^^ help: consider using: `x.ln()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> $DIR/floating_point_log.rs:17:13 + --> $DIR/floating_point_log.rs:15:13 + | +LL | let _ = (x as f32).log(2f32); + | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log2()` + +error: logarithm for bases 2, 10 and e can be computed more accurately + --> $DIR/floating_point_log.rs:18:13 | LL | let _ = x.log(2f64); | ^^^^^^^^^^^ help: consider using: `x.log2()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> $DIR/floating_point_log.rs:18:13 + --> $DIR/floating_point_log.rs:19:13 | LL | let _ = x.log(10f64); | ^^^^^^^^^^^^ help: consider using: `x.log10()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> $DIR/floating_point_log.rs:19:13 + --> $DIR/floating_point_log.rs:20:13 | LL | let _ = x.log(std::f64::consts::E); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:24:13 + --> $DIR/floating_point_log.rs:25:13 | LL | let _ = (1f32 + 2.).ln(); | ^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` @@ -57,118 +63,118 @@ LL | let _ = (1f32 + 2.).ln(); = note: `-D clippy::imprecise-flops` implied by `-D warnings` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:25:13 + --> $DIR/floating_point_log.rs:26:13 | LL | let _ = (1f32 + 2.0).ln(); | ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:26:13 + --> $DIR/floating_point_log.rs:27:13 | LL | let _ = (1.0 + x).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:27:13 + --> $DIR/floating_point_log.rs:28:13 | LL | let _ = (1.0 + x / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:28:13 + --> $DIR/floating_point_log.rs:29:13 | LL | let _ = (1.0 + x.powi(3)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:29:13 + --> $DIR/floating_point_log.rs:30:13 | LL | let _ = (1.0 + x.powi(3) / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(3) / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:30:13 + --> $DIR/floating_point_log.rs:31:13 | LL | let _ = (1.0 + (std::f32::consts::E - 1.0)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(std::f32::consts::E - 1.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:31:13 + --> $DIR/floating_point_log.rs:32:13 | LL | let _ = (x + 1.0).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:32:13 + --> $DIR/floating_point_log.rs:33:13 | LL | let _ = (x.powi(3) + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:33:13 + --> $DIR/floating_point_log.rs:34:13 | LL | let _ = (x + 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:34:13 + --> $DIR/floating_point_log.rs:35:13 | LL | let _ = (x / 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:42:13 + --> $DIR/floating_point_log.rs:43:13 | LL | let _ = (1f64 + 2.).ln(); | ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:43:13 + --> $DIR/floating_point_log.rs:44:13 | LL | let _ = (1f64 + 2.0).ln(); | ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:44:13 + --> $DIR/floating_point_log.rs:45:13 | LL | let _ = (1.0 + x).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:45:13 + --> $DIR/floating_point_log.rs:46:13 | LL | let _ = (1.0 + x / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:46:13 + --> $DIR/floating_point_log.rs:47:13 | LL | let _ = (1.0 + x.powi(3)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:47:13 + --> $DIR/floating_point_log.rs:48:13 | LL | let _ = (x + 1.0).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:48:13 + --> $DIR/floating_point_log.rs:49:13 | LL | let _ = (x.powi(3) + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:49:13 + --> $DIR/floating_point_log.rs:50:13 | LL | let _ = (x + 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> $DIR/floating_point_log.rs:50:13 + --> $DIR/floating_point_log.rs:51:13 | LL | let _ = (x / 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` -error: aborting due to 28 previous errors +error: aborting due to 29 previous errors diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.fixed b/src/tools/clippy/tests/ui/floating_point_logbase.fixed index 13962a272..936462f94 100644 --- a/src/tools/clippy/tests/ui/floating_point_logbase.fixed +++ b/src/tools/clippy/tests/ui/floating_point_logbase.fixed @@ -5,6 +5,7 @@ fn main() { let x = 3f32; let y = 5f32; let _ = x.log(y); + let _ = (x as f32).log(y); let _ = x.log(y); let _ = x.log(y); let _ = x.log(y); diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.rs b/src/tools/clippy/tests/ui/floating_point_logbase.rs index 26bc20d53..0b56fa8fa 100644 --- a/src/tools/clippy/tests/ui/floating_point_logbase.rs +++ b/src/tools/clippy/tests/ui/floating_point_logbase.rs @@ -5,6 +5,7 @@ fn main() { let x = 3f32; let y = 5f32; let _ = x.ln() / y.ln(); + let _ = (x as f32).ln() / y.ln(); let _ = x.log2() / y.log2(); let _ = x.log10() / y.log10(); let _ = x.log(5f32) / y.log(5f32); diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.stderr b/src/tools/clippy/tests/ui/floating_point_logbase.stderr index 78354c2f6..384e3554c 100644 --- a/src/tools/clippy/tests/ui/floating_point_logbase.stderr +++ b/src/tools/clippy/tests/ui/floating_point_logbase.stderr @@ -9,20 +9,26 @@ LL | let _ = x.ln() / y.ln(); error: log base can be expressed more clearly --> $DIR/floating_point_logbase.rs:8:13 | +LL | let _ = (x as f32).ln() / y.ln(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log(y)` + +error: log base can be expressed more clearly + --> $DIR/floating_point_logbase.rs:9:13 + | LL | let _ = x.log2() / y.log2(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` error: log base can be expressed more clearly - --> $DIR/floating_point_logbase.rs:9:13 + --> $DIR/floating_point_logbase.rs:10:13 | LL | let _ = x.log10() / y.log10(); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` error: log base can be expressed more clearly - --> $DIR/floating_point_logbase.rs:10:13 + --> $DIR/floating_point_logbase.rs:11:13 | LL | let _ = x.log(5f32) / y.log(5f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/floating_point_powf.fixed b/src/tools/clippy/tests/ui/floating_point_powf.fixed index b0641a100..e7ef45634 100644 --- a/src/tools/clippy/tests/ui/floating_point_powf.fixed +++ b/src/tools/clippy/tests/ui/floating_point_powf.fixed @@ -11,10 +11,18 @@ fn main() { let _ = (-3.1f32).exp(); let _ = x.sqrt(); let _ = x.cbrt(); + let _ = (x as f32).cbrt(); let _ = x.powi(3); let _ = x.powi(-2); let _ = x.powi(16_777_215); let _ = x.powi(-16_777_215); + let _ = (x as f32).powi(-16_777_215); + let _ = (x as f32).powi(3); + let _ = (1.5_f32 + 1.0).cbrt(); + let _ = 1.5_f64.cbrt(); + let _ = 1.5_f64.sqrt(); + let _ = 1.5_f64.powi(3); + // Cases where the lint shouldn't be applied let _ = x.powf(2.1); let _ = x.powf(-2.1); diff --git a/src/tools/clippy/tests/ui/floating_point_powf.rs b/src/tools/clippy/tests/ui/floating_point_powf.rs index a0a2c9739..d749aa2d4 100644 --- a/src/tools/clippy/tests/ui/floating_point_powf.rs +++ b/src/tools/clippy/tests/ui/floating_point_powf.rs @@ -11,10 +11,18 @@ fn main() { let _ = std::f32::consts::E.powf(-3.1); let _ = x.powf(1.0 / 2.0); let _ = x.powf(1.0 / 3.0); + let _ = (x as f32).powf(1.0 / 3.0); let _ = x.powf(3.0); let _ = x.powf(-2.0); let _ = x.powf(16_777_215.0); let _ = x.powf(-16_777_215.0); + let _ = (x as f32).powf(-16_777_215.0); + let _ = (x as f32).powf(3.0); + let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0); + let _ = 1.5_f64.powf(1.0 / 3.0); + let _ = 1.5_f64.powf(1.0 / 2.0); + let _ = 1.5_f64.powf(3.0); + // Cases where the lint shouldn't be applied let _ = x.powf(2.1); let _ = x.powf(-2.1); diff --git a/src/tools/clippy/tests/ui/floating_point_powf.stderr b/src/tools/clippy/tests/ui/floating_point_powf.stderr index 2422eb911..e9693de8f 100644 --- a/src/tools/clippy/tests/ui/floating_point_powf.stderr +++ b/src/tools/clippy/tests/ui/floating_point_powf.stderr @@ -50,101 +50,143 @@ LL | let _ = x.powf(1.0 / 3.0); | = note: `-D clippy::imprecise-flops` implied by `-D warnings` -error: exponentiation with integer powers can be computed more efficiently +error: cube-root of a number can be computed more accurately --> $DIR/floating_point_powf.rs:14:13 | +LL | let _ = (x as f32).powf(1.0 / 3.0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).cbrt()` + +error: exponentiation with integer powers can be computed more efficiently + --> $DIR/floating_point_powf.rs:15:13 + | LL | let _ = x.powf(3.0); | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently - --> $DIR/floating_point_powf.rs:15:13 + --> $DIR/floating_point_powf.rs:16:13 | LL | let _ = x.powf(-2.0); | ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` error: exponentiation with integer powers can be computed more efficiently - --> $DIR/floating_point_powf.rs:16:13 + --> $DIR/floating_point_powf.rs:17:13 | LL | let _ = x.powf(16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)` error: exponentiation with integer powers can be computed more efficiently - --> $DIR/floating_point_powf.rs:17:13 + --> $DIR/floating_point_powf.rs:18:13 | LL | let _ = x.powf(-16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)` +error: exponentiation with integer powers can be computed more efficiently + --> $DIR/floating_point_powf.rs:19:13 + | +LL | let _ = (x as f32).powf(-16_777_215.0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(-16_777_215)` + +error: exponentiation with integer powers can be computed more efficiently + --> $DIR/floating_point_powf.rs:20:13 + | +LL | let _ = (x as f32).powf(3.0); + | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(3)` + +error: cube-root of a number can be computed more accurately + --> $DIR/floating_point_powf.rs:21:13 + | +LL | let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1.5_f32 + 1.0).cbrt()` + +error: cube-root of a number can be computed more accurately + --> $DIR/floating_point_powf.rs:22:13 + | +LL | let _ = 1.5_f64.powf(1.0 / 3.0); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.cbrt()` + +error: square-root of a number can be computed more efficiently and accurately + --> $DIR/floating_point_powf.rs:23:13 + | +LL | let _ = 1.5_f64.powf(1.0 / 2.0); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.sqrt()` + +error: exponentiation with integer powers can be computed more efficiently + --> $DIR/floating_point_powf.rs:24:13 + | +LL | let _ = 1.5_f64.powf(3.0); + | ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)` + error: exponent for bases 2 and e can be computed more accurately - --> $DIR/floating_point_powf.rs:25:13 + --> $DIR/floating_point_powf.rs:33:13 | LL | let _ = 2f64.powf(x); | ^^^^^^^^^^^^ help: consider using: `x.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> $DIR/floating_point_powf.rs:26:13 + --> $DIR/floating_point_powf.rs:34:13 | LL | let _ = 2f64.powf(3.1); | ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> $DIR/floating_point_powf.rs:27:13 + --> $DIR/floating_point_powf.rs:35:13 | LL | let _ = 2f64.powf(-3.1); | ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()` error: exponent for bases 2 and e can be computed more accurately - --> $DIR/floating_point_powf.rs:28:13 + --> $DIR/floating_point_powf.rs:36:13 | LL | let _ = std::f64::consts::E.powf(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()` error: exponent for bases 2 and e can be computed more accurately - --> $DIR/floating_point_powf.rs:29:13 + --> $DIR/floating_point_powf.rs:37:13 | LL | let _ = std::f64::consts::E.powf(3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()` error: exponent for bases 2 and e can be computed more accurately - --> $DIR/floating_point_powf.rs:30:13 + --> $DIR/floating_point_powf.rs:38:13 | LL | let _ = std::f64::consts::E.powf(-3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()` error: square-root of a number can be computed more efficiently and accurately - --> $DIR/floating_point_powf.rs:31:13 + --> $DIR/floating_point_powf.rs:39:13 | LL | let _ = x.powf(1.0 / 2.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()` error: cube-root of a number can be computed more accurately - --> $DIR/floating_point_powf.rs:32:13 + --> $DIR/floating_point_powf.rs:40:13 | LL | let _ = x.powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()` error: exponentiation with integer powers can be computed more efficiently - --> $DIR/floating_point_powf.rs:33:13 + --> $DIR/floating_point_powf.rs:41:13 | LL | let _ = x.powf(3.0); | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently - --> $DIR/floating_point_powf.rs:34:13 + --> $DIR/floating_point_powf.rs:42:13 | LL | let _ = x.powf(-2.0); | ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` error: exponentiation with integer powers can be computed more efficiently - --> $DIR/floating_point_powf.rs:35:13 + --> $DIR/floating_point_powf.rs:43:13 | LL | let _ = x.powf(-2_147_483_648.0); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)` error: exponentiation with integer powers can be computed more efficiently - --> $DIR/floating_point_powf.rs:36:13 + --> $DIR/floating_point_powf.rs:44:13 | LL | let _ = x.powf(2_147_483_647.0); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)` -error: aborting due to 24 previous errors +error: aborting due to 31 previous errors diff --git a/src/tools/clippy/tests/ui/floating_point_powi.fixed b/src/tools/clippy/tests/ui/floating_point_powi.fixed index 85f7c531e..5758db7c6 100644 --- a/src/tools/clippy/tests/ui/floating_point_powi.fixed +++ b/src/tools/clippy/tests/ui/floating_point_powi.fixed @@ -8,6 +8,7 @@ fn main() { let y = 4f32; let _ = x.mul_add(x, y); let _ = y.mul_add(y, x); + let _ = (y as f32).mul_add(y as f32, x); let _ = x.mul_add(x, y).sqrt(); let _ = y.mul_add(y, x).sqrt(); // Cases where the lint shouldn't be applied diff --git a/src/tools/clippy/tests/ui/floating_point_powi.rs b/src/tools/clippy/tests/ui/floating_point_powi.rs index ece61d1be..5926bf1b0 100644 --- a/src/tools/clippy/tests/ui/floating_point_powi.rs +++ b/src/tools/clippy/tests/ui/floating_point_powi.rs @@ -8,6 +8,7 @@ fn main() { let y = 4f32; let _ = x.powi(2) + y; let _ = x + y.powi(2); + let _ = x + (y as f32).powi(2); let _ = (x.powi(2) + y).sqrt(); let _ = (x + y.powi(2)).sqrt(); // Cases where the lint shouldn't be applied diff --git a/src/tools/clippy/tests/ui/floating_point_powi.stderr b/src/tools/clippy/tests/ui/floating_point_powi.stderr index 37d840988..a3c745442 100644 --- a/src/tools/clippy/tests/ui/floating_point_powi.stderr +++ b/src/tools/clippy/tests/ui/floating_point_powi.stderr @@ -15,14 +15,20 @@ LL | let _ = x + y.powi(2); error: multiply and add expressions can be calculated more efficiently and accurately --> $DIR/floating_point_powi.rs:11:13 | +LL | let _ = x + (y as f32).powi(2); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y as f32).mul_add(y as f32, x)` + +error: multiply and add expressions can be calculated more efficiently and accurately + --> $DIR/floating_point_powi.rs:12:13 + | LL | let _ = (x.powi(2) + y).sqrt(); | ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)` error: multiply and add expressions can be calculated more efficiently and accurately - --> $DIR/floating_point_powi.rs:12:13 + --> $DIR/floating_point_powi.rs:13:13 | LL | let _ = (x + y.powi(2)).sqrt(); | ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/floating_point_rad.fixed b/src/tools/clippy/tests/ui/floating_point_rad.fixed index ce91fe176..27674b8a4 100644 --- a/src/tools/clippy/tests/ui/floating_point_rad.fixed +++ b/src/tools/clippy/tests/ui/floating_point_rad.fixed @@ -8,6 +8,11 @@ pub const fn const_context() { let _ = x * 180f32 / std::f32::consts::PI; } +pub fn issue9391(degrees: i64) { + let _ = (degrees as f64).to_radians(); + let _ = (degrees as f64).to_degrees(); +} + fn main() { let x = 3f32; let _ = x.to_degrees(); diff --git a/src/tools/clippy/tests/ui/floating_point_rad.rs b/src/tools/clippy/tests/ui/floating_point_rad.rs index 8f3234986..f1ea73df3 100644 --- a/src/tools/clippy/tests/ui/floating_point_rad.rs +++ b/src/tools/clippy/tests/ui/floating_point_rad.rs @@ -8,6 +8,11 @@ pub const fn const_context() { let _ = x * 180f32 / std::f32::consts::PI; } +pub fn issue9391(degrees: i64) { + let _ = degrees as f64 * std::f64::consts::PI / 180.0; + let _ = degrees as f64 * 180.0 / std::f64::consts::PI; +} + fn main() { let x = 3f32; let _ = x * 180f32 / std::f32::consts::PI; diff --git a/src/tools/clippy/tests/ui/floating_point_rad.stderr b/src/tools/clippy/tests/ui/floating_point_rad.stderr index f12d3d23f..979442f2c 100644 --- a/src/tools/clippy/tests/ui/floating_point_rad.stderr +++ b/src/tools/clippy/tests/ui/floating_point_rad.stderr @@ -1,40 +1,52 @@ +error: conversion to radians can be done more accurately + --> $DIR/floating_point_rad.rs:12:13 + | +LL | let _ = degrees as f64 * std::f64::consts::PI / 180.0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_radians()` + | + = note: `-D clippy::suboptimal-flops` implied by `-D warnings` + error: conversion to degrees can be done more accurately --> $DIR/floating_point_rad.rs:13:13 | +LL | let _ = degrees as f64 * 180.0 / std::f64::consts::PI; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()` + +error: conversion to degrees can be done more accurately + --> $DIR/floating_point_rad.rs:18:13 + | LL | let _ = x * 180f32 / std::f32::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()` - | - = note: `-D clippy::suboptimal-flops` implied by `-D warnings` error: conversion to degrees can be done more accurately - --> $DIR/floating_point_rad.rs:14:13 + --> $DIR/floating_point_rad.rs:19:13 | LL | let _ = 90. * 180f64 / std::f64::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()` error: conversion to degrees can be done more accurately - --> $DIR/floating_point_rad.rs:15:13 + --> $DIR/floating_point_rad.rs:20:13 | LL | let _ = 90.5 * 180f64 / std::f64::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()` error: conversion to radians can be done more accurately - --> $DIR/floating_point_rad.rs:16:13 + --> $DIR/floating_point_rad.rs:21:13 | LL | let _ = x * std::f32::consts::PI / 180f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()` error: conversion to radians can be done more accurately - --> $DIR/floating_point_rad.rs:17:13 + --> $DIR/floating_point_rad.rs:22:13 | LL | let _ = 90. * std::f32::consts::PI / 180f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()` error: conversion to radians can be done more accurately - --> $DIR/floating_point_rad.rs:18:13 + --> $DIR/floating_point_rad.rs:23:13 | LL | let _ = 90.5 * std::f32::consts::PI / 180f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()` -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/format.fixed b/src/tools/clippy/tests/ui/format.fixed index 6b754f3bd..b56d6aec5 100644 --- a/src/tools/clippy/tests/ui/format.fixed +++ b/src/tools/clippy/tests/ui/format.fixed @@ -33,7 +33,7 @@ fn main() { format!("foo {}", "bar"); format!("{} bar", "foo"); - let arg: String = "".to_owned(); + let arg = String::new(); arg.to_string(); format!("{:?}", arg); // Don't warn about debug. format!("{:8}", arg); diff --git a/src/tools/clippy/tests/ui/format.rs b/src/tools/clippy/tests/ui/format.rs index ca9826b35..4c1a3a840 100644 --- a/src/tools/clippy/tests/ui/format.rs +++ b/src/tools/clippy/tests/ui/format.rs @@ -35,7 +35,7 @@ fn main() { format!("foo {}", "bar"); format!("{} bar", "foo"); - let arg: String = "".to_owned(); + let arg = String::new(); format!("{}", arg); format!("{:?}", arg); // Don't warn about debug. format!("{:8}", arg); diff --git a/src/tools/clippy/tests/ui/format_args.fixed b/src/tools/clippy/tests/ui/format_args.fixed index 69b5e1c72..e1c2d4d70 100644 --- a/src/tools/clippy/tests/ui/format_args.fixed +++ b/src/tools/clippy/tests/ui/format_args.fixed @@ -1,8 +1,6 @@ // run-rustfix -#![allow(unreachable_code)] -#![allow(unused_macros)] -#![allow(unused_variables)] +#![allow(unused)] #![allow(clippy::assertions_on_constants)] #![allow(clippy::eq_op)] #![allow(clippy::print_literal)] @@ -115,3 +113,50 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/7903 println!("{foo}{foo:?}", foo = "foo".to_string()); } + +fn issue8643(vendor_id: usize, product_id: usize, name: &str) { + println!( + "{:<9} {:<10} {}", + format!("0x{:x}", vendor_id), + format!("0x{:x}", product_id), + name + ); +} + +// https://github.com/rust-lang/rust-clippy/issues/8855 +mod issue_8855 { + #![allow(dead_code)] + + struct A {} + + impl std::fmt::Display for A { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "test") + } + } + + fn main() { + let a = A {}; + let b = A {}; + + let x = format!("{} {}", a, b); + dbg!(x); + + let x = format!("{:>6} {:>6}", a, b.to_string()); + dbg!(x); + } +} + +// https://github.com/rust-lang/rust-clippy/issues/9256 +mod issue_9256 { + #![allow(dead_code)] + + fn print_substring(original: &str) { + assert!(original.len() > 10); + println!("{}", &original[..10]); + } + + fn main() { + print_substring("Hello, world!"); + } +} diff --git a/src/tools/clippy/tests/ui/format_args.rs b/src/tools/clippy/tests/ui/format_args.rs index 3a434c5bf..b9a4d66c2 100644 --- a/src/tools/clippy/tests/ui/format_args.rs +++ b/src/tools/clippy/tests/ui/format_args.rs @@ -1,8 +1,6 @@ // run-rustfix -#![allow(unreachable_code)] -#![allow(unused_macros)] -#![allow(unused_variables)] +#![allow(unused)] #![allow(clippy::assertions_on_constants)] #![allow(clippy::eq_op)] #![allow(clippy::print_literal)] @@ -115,3 +113,50 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/7903 println!("{foo}{foo:?}", foo = "foo".to_string()); } + +fn issue8643(vendor_id: usize, product_id: usize, name: &str) { + println!( + "{:<9} {:<10} {}", + format!("0x{:x}", vendor_id), + format!("0x{:x}", product_id), + name + ); +} + +// https://github.com/rust-lang/rust-clippy/issues/8855 +mod issue_8855 { + #![allow(dead_code)] + + struct A {} + + impl std::fmt::Display for A { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "test") + } + } + + fn main() { + let a = A {}; + let b = A {}; + + let x = format!("{} {}", a, b.to_string()); + dbg!(x); + + let x = format!("{:>6} {:>6}", a, b.to_string()); + dbg!(x); + } +} + +// https://github.com/rust-lang/rust-clippy/issues/9256 +mod issue_9256 { + #![allow(dead_code)] + + fn print_substring(original: &str) { + assert!(original.len() > 10); + println!("{}", original[..10].to_string()); + } + + fn main() { + print_substring("Hello, world!"); + } +} diff --git a/src/tools/clippy/tests/ui/format_args.stderr b/src/tools/clippy/tests/ui/format_args.stderr index c0cbca507..aa6e3659b 100644 --- a/src/tools/clippy/tests/ui/format_args.stderr +++ b/src/tools/clippy/tests/ui/format_args.stderr @@ -1,5 +1,5 @@ error: `to_string` applied to a type that implements `Display` in `format!` args - --> $DIR/format_args.rs:76:72 + --> $DIR/format_args.rs:74:72 | LL | let _ = format!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this @@ -7,124 +7,136 @@ LL | let _ = format!("error: something failed at {}", Location::caller().to_ = note: `-D clippy::to-string-in-format-args` implied by `-D warnings` error: `to_string` applied to a type that implements `Display` in `write!` args - --> $DIR/format_args.rs:80:27 + --> $DIR/format_args.rs:78:27 | LL | Location::caller().to_string() | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `writeln!` args - --> $DIR/format_args.rs:85:27 + --> $DIR/format_args.rs:83:27 | LL | Location::caller().to_string() | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `print!` args - --> $DIR/format_args.rs:87:63 + --> $DIR/format_args.rs:85:63 | LL | print!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:88:65 + --> $DIR/format_args.rs:86:65 | LL | println!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `eprint!` args - --> $DIR/format_args.rs:89:64 + --> $DIR/format_args.rs:87:64 | LL | eprint!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `eprintln!` args - --> $DIR/format_args.rs:90:66 + --> $DIR/format_args.rs:88:66 | LL | eprintln!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `format_args!` args - --> $DIR/format_args.rs:91:77 + --> $DIR/format_args.rs:89:77 | LL | let _ = format_args!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `assert!` args - --> $DIR/format_args.rs:92:70 + --> $DIR/format_args.rs:90:70 | LL | assert!(true, "error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `assert_eq!` args - --> $DIR/format_args.rs:93:73 + --> $DIR/format_args.rs:91:73 | LL | assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `assert_ne!` args - --> $DIR/format_args.rs:94:73 + --> $DIR/format_args.rs:92:73 | LL | assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `panic!` args - --> $DIR/format_args.rs:95:63 + --> $DIR/format_args.rs:93:63 | LL | panic!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:96:20 + --> $DIR/format_args.rs:94:20 | LL | println!("{}", X(1).to_string()); | ^^^^^^^^^^^^^^^^ help: use this: `*X(1)` error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:97:20 + --> $DIR/format_args.rs:95:20 | LL | println!("{}", Y(&X(1)).to_string()); | ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))` error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:98:24 + --> $DIR/format_args.rs:96:24 | LL | println!("{}", Z(1).to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:99:20 + --> $DIR/format_args.rs:97:20 | LL | println!("{}", x.to_string()); | ^^^^^^^^^^^^^ help: use this: `**x` error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:100:20 + --> $DIR/format_args.rs:98:20 | LL | println!("{}", x_ref.to_string()); | ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref` error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:102:39 + --> $DIR/format_args.rs:100:39 | LL | println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar"); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:103:52 + --> $DIR/format_args.rs:101:52 | LL | println!("{foo}{bar}", foo = "foo", bar = "bar".to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:104:39 + --> $DIR/format_args.rs:102:39 | LL | println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo"); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> $DIR/format_args.rs:105:52 + --> $DIR/format_args.rs:103:52 | LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string()); | ^^^^^^^^^^^^ help: remove this -error: aborting due to 21 previous errors +error: `to_string` applied to a type that implements `Display` in `format!` args + --> $DIR/format_args.rs:142:38 + | +LL | let x = format!("{} {}", a, b.to_string()); + | ^^^^^^^^^^^^ help: remove this + +error: `to_string` applied to a type that implements `Display` in `println!` args + --> $DIR/format_args.rs:156:24 + | +LL | println!("{}", original[..10].to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]` + +error: aborting due to 23 previous errors diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed index 5f9cebe21..fa564e23c 100644 --- a/src/tools/clippy/tests/ui/identity_op.fixed +++ b/src/tools/clippy/tests/ui/identity_op.fixed @@ -68,7 +68,7 @@ fn main() { &x; x; - let mut a = A("".into()); + let mut a = A(String::new()); let b = a << 0; // no error: non-integer 1 * Meter; // no error: non-integer diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs index ca799c9cf..3d06d2a73 100644 --- a/src/tools/clippy/tests/ui/identity_op.rs +++ b/src/tools/clippy/tests/ui/identity_op.rs @@ -68,7 +68,7 @@ fn main() { &x >> 0; x >> &0; - let mut a = A("".into()); + let mut a = A(String::new()); let b = a << 0; // no error: non-integer 1 * Meter; // no error: non-integer diff --git a/src/tools/clippy/tests/ui/if_let_mutex.rs b/src/tools/clippy/tests/ui/if_let_mutex.rs index 6cbfafbb3..321feb022 100644 --- a/src/tools/clippy/tests/ui/if_let_mutex.rs +++ b/src/tools/clippy/tests/ui/if_let_mutex.rs @@ -39,4 +39,12 @@ fn if_let_different_mutex() { }; } +fn mutex_ref(mutex: &Mutex<i32>) { + if let Ok(i) = mutex.lock() { + do_stuff(i); + } else { + let _x = mutex.lock(); + }; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/if_let_mutex.stderr b/src/tools/clippy/tests/ui/if_let_mutex.stderr index e9c4d9163..8a4d5dbac 100644 --- a/src/tools/clippy/tests/ui/if_let_mutex.stderr +++ b/src/tools/clippy/tests/ui/if_let_mutex.stderr @@ -1,10 +1,14 @@ error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock --> $DIR/if_let_mutex.rs:10:5 | -LL | / if let Err(locked) = m.lock() { +LL | if let Err(locked) = m.lock() { + | ^ - this Mutex will remain locked for the entire `if let`-block... + | _____| + | | LL | | do_stuff(locked); LL | | } else { LL | | let lock = m.lock().unwrap(); + | | - ... and is tried to lock again here, which will always deadlock. LL | | do_stuff(lock); LL | | }; | |_____^ @@ -15,15 +19,35 @@ LL | | }; error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock --> $DIR/if_let_mutex.rs:22:5 | -LL | / if let Some(locked) = m.lock().unwrap().deref() { +LL | if let Some(locked) = m.lock().unwrap().deref() { + | ^ - this Mutex will remain locked for the entire `if let`-block... + | _____| + | | LL | | do_stuff(locked); LL | | } else { LL | | let lock = m.lock().unwrap(); + | | - ... and is tried to lock again here, which will always deadlock. LL | | do_stuff(lock); LL | | }; | |_____^ | = help: move the lock call outside of the `if let ...` expression -error: aborting due to 2 previous errors +error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock + --> $DIR/if_let_mutex.rs:43:5 + | +LL | if let Ok(i) = mutex.lock() { + | ^ ----- this Mutex will remain locked for the entire `if let`-block... + | _____| + | | +LL | | do_stuff(i); +LL | | } else { +LL | | let _x = mutex.lock(); + | | ----- ... and is tried to lock again here, which will always deadlock. +LL | | }; + | |_____^ + | + = help: move the lock call outside of the `if let ...` expression + +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/if_same_then_else.rs b/src/tools/clippy/tests/ui/if_same_then_else.rs index 2598c2ab4..07d2002eb 100644 --- a/src/tools/clippy/tests/ui/if_same_then_else.rs +++ b/src/tools/clippy/tests/ui/if_same_then_else.rs @@ -1,6 +1,6 @@ #![warn(clippy::if_same_then_else)] #![allow( - clippy::blacklisted_name, + clippy::disallowed_names, clippy::eq_op, clippy::never_loop, clippy::no_effect, diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.rs b/src/tools/clippy/tests/ui/if_same_then_else2.rs index 0016009a0..58167f444 100644 --- a/src/tools/clippy/tests/ui/if_same_then_else2.rs +++ b/src/tools/clippy/tests/ui/if_same_then_else2.rs @@ -1,6 +1,6 @@ #![warn(clippy::if_same_then_else)] #![allow( - clippy::blacklisted_name, + clippy::disallowed_names, clippy::collapsible_else_if, clippy::equatable_if_let, clippy::collapsible_if, diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr index 8cb22d569..c22ace30d 100644 --- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr +++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr @@ -27,21 +27,21 @@ LL | | }; | = help: consider using `bool::then` like: `matches!(true, true).then(|| { /* snippet */ matches!(true, false) })` -error: this could be simplified with `bool::then` +error: this could be simplified with `bool::then_some` --> $DIR/if_then_some_else_none.rs:23:28 | LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider using `bool::then` like: `(o < 32).then(|| o)` + = help: consider using `bool::then_some` like: `(o < 32).then_some(o)` -error: this could be simplified with `bool::then` +error: this could be simplified with `bool::then_some` --> $DIR/if_then_some_else_none.rs:27:13 | LL | let _ = if !x { Some(0) } else { None }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider using `bool::then` like: `(!x).then(|| 0)` + = help: consider using `bool::then_some` like: `(!x).then_some(0)` error: this could be simplified with `bool::then` --> $DIR/if_then_some_else_none.rs:82:13 diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.rs b/src/tools/clippy/tests/ui/ifs_same_cond.rs index 80e9839ff..9850fc091 100644 --- a/src/tools/clippy/tests/ui/ifs_same_cond.rs +++ b/src/tools/clippy/tests/ui/ifs_same_cond.rs @@ -32,9 +32,9 @@ fn ifs_same_cond() { }; let mut v = vec![1]; - if v.pop() == None { + if v.pop().is_none() { // ok, functions - } else if v.pop() == None { + } else if v.pop().is_none() { } if v.len() == 42 { diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs index 45a430edc..7ebf6ee99 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs +++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs @@ -3,7 +3,7 @@ // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. #![warn(clippy::out_of_bounds_indexing)] -#![allow(const_err, clippy::no_effect, clippy::unnecessary_operation)] +#![allow(const_err, unconditional_panic, clippy::no_effect, clippy::unnecessary_operation)] const ARR: [i32; 2] = [1, 2]; const REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr. diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed new file mode 100644 index 000000000..bd9b07aef --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed @@ -0,0 +1,63 @@ +// run-rustfix +#![warn(clippy::iter_on_empty_collections)] +#![allow(clippy::iter_next_slice, clippy::redundant_clone)] + +fn array() { + assert_eq!(std::iter::empty().next(), Option::<i32>::None); + assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None); + assert_eq!(std::iter::empty().next(), Option::<&i32>::None); + assert_eq!(std::iter::empty().next(), Option::<i32>::None); + assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None); + assert_eq!(std::iter::empty().next(), Option::<&i32>::None); + + // Don't trigger on non-iter methods + let _: Option<String> = None.clone(); + let _: [String; 0] = [].clone(); + + // Don't trigger on match or if branches + let _ = match 123 { + 123 => [].iter(), + _ => ["test"].iter(), + }; + + let _ = if false { ["test"].iter() } else { [].iter() }; +} + +macro_rules! in_macros { + () => { + assert_eq!([].into_iter().next(), Option::<i32>::None); + assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); + assert_eq!([].iter().next(), Option::<&i32>::None); + assert_eq!(None.into_iter().next(), Option::<i32>::None); + assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); + assert_eq!(None.iter().next(), Option::<&i32>::None); + }; +} + +// Don't trigger on a `None` that isn't std's option +mod custom_option { + #[allow(unused)] + enum CustomOption { + Some(i32), + None, + } + + impl CustomOption { + fn iter(&self) {} + fn iter_mut(&mut self) {} + fn into_iter(self) {} + } + use CustomOption::*; + + pub fn custom_option() { + None.iter(); + None.iter_mut(); + None.into_iter(); + } +} + +fn main() { + array(); + custom_option::custom_option(); + in_macros!(); +} diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs new file mode 100644 index 000000000..e15ba94bd --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs @@ -0,0 +1,63 @@ +// run-rustfix +#![warn(clippy::iter_on_empty_collections)] +#![allow(clippy::iter_next_slice, clippy::redundant_clone)] + +fn array() { + assert_eq!([].into_iter().next(), Option::<i32>::None); + assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); + assert_eq!([].iter().next(), Option::<&i32>::None); + assert_eq!(None.into_iter().next(), Option::<i32>::None); + assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); + assert_eq!(None.iter().next(), Option::<&i32>::None); + + // Don't trigger on non-iter methods + let _: Option<String> = None.clone(); + let _: [String; 0] = [].clone(); + + // Don't trigger on match or if branches + let _ = match 123 { + 123 => [].iter(), + _ => ["test"].iter(), + }; + + let _ = if false { ["test"].iter() } else { [].iter() }; +} + +macro_rules! in_macros { + () => { + assert_eq!([].into_iter().next(), Option::<i32>::None); + assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); + assert_eq!([].iter().next(), Option::<&i32>::None); + assert_eq!(None.into_iter().next(), Option::<i32>::None); + assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); + assert_eq!(None.iter().next(), Option::<&i32>::None); + }; +} + +// Don't trigger on a `None` that isn't std's option +mod custom_option { + #[allow(unused)] + enum CustomOption { + Some(i32), + None, + } + + impl CustomOption { + fn iter(&self) {} + fn iter_mut(&mut self) {} + fn into_iter(self) {} + } + use CustomOption::*; + + pub fn custom_option() { + None.iter(); + None.iter_mut(); + None.into_iter(); + } +} + +fn main() { + array(); + custom_option::custom_option(); + in_macros!(); +} diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr new file mode 100644 index 000000000..cbd611769 --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr @@ -0,0 +1,40 @@ +error: `into_iter` call on an empty collection + --> $DIR/iter_on_empty_collections.rs:6:16 + | +LL | assert_eq!([].into_iter().next(), Option::<i32>::None); + | ^^^^^^^^^^^^^^ help: try: `std::iter::empty()` + | + = note: `-D clippy::iter-on-empty-collections` implied by `-D warnings` + +error: `iter_mut` call on an empty collection + --> $DIR/iter_on_empty_collections.rs:7:16 + | +LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); + | ^^^^^^^^^^^^^ help: try: `std::iter::empty()` + +error: `iter` call on an empty collection + --> $DIR/iter_on_empty_collections.rs:8:16 + | +LL | assert_eq!([].iter().next(), Option::<&i32>::None); + | ^^^^^^^^^ help: try: `std::iter::empty()` + +error: `into_iter` call on an empty collection + --> $DIR/iter_on_empty_collections.rs:9:16 + | +LL | assert_eq!(None.into_iter().next(), Option::<i32>::None); + | ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()` + +error: `iter_mut` call on an empty collection + --> $DIR/iter_on_empty_collections.rs:10:16 + | +LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); + | ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()` + +error: `iter` call on an empty collection + --> $DIR/iter_on_empty_collections.rs:11:16 + | +LL | assert_eq!(None.iter().next(), Option::<&i32>::None); + | ^^^^^^^^^^^ help: try: `std::iter::empty()` + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.fixed b/src/tools/clippy/tests/ui/iter_on_single_items.fixed new file mode 100644 index 000000000..1fa4b0364 --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_on_single_items.fixed @@ -0,0 +1,63 @@ +// run-rustfix +#![warn(clippy::iter_on_single_items)] +#![allow(clippy::iter_next_slice, clippy::redundant_clone)] + +fn array() { + assert_eq!(std::iter::once(123).next(), Some(123)); + assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123)); + assert_eq!(std::iter::once(&123).next(), Some(&123)); + assert_eq!(std::iter::once(123).next(), Some(123)); + assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123)); + assert_eq!(std::iter::once(&123).next(), Some(&123)); + + // Don't trigger on non-iter methods + let _: Option<String> = Some("test".to_string()).clone(); + let _: [String; 1] = ["test".to_string()].clone(); + + // Don't trigger on match or if branches + let _ = match 123 { + 123 => [].iter(), + _ => ["test"].iter(), + }; + + let _ = if false { ["test"].iter() } else { [].iter() }; +} + +macro_rules! in_macros { + () => { + assert_eq!([123].into_iter().next(), Some(123)); + assert_eq!([123].iter_mut().next(), Some(&mut 123)); + assert_eq!([123].iter().next(), Some(&123)); + assert_eq!(Some(123).into_iter().next(), Some(123)); + assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); + assert_eq!(Some(123).iter().next(), Some(&123)); + }; +} + +// Don't trigger on a `Some` that isn't std's option +mod custom_option { + #[allow(unused)] + enum CustomOption { + Some(i32), + None, + } + + impl CustomOption { + fn iter(&self) {} + fn iter_mut(&mut self) {} + fn into_iter(self) {} + } + use CustomOption::*; + + pub fn custom_option() { + Some(3).iter(); + Some(3).iter_mut(); + Some(3).into_iter(); + } +} + +fn main() { + array(); + custom_option::custom_option(); + in_macros!(); +} diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.rs b/src/tools/clippy/tests/ui/iter_on_single_items.rs new file mode 100644 index 000000000..ea96d8066 --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_on_single_items.rs @@ -0,0 +1,63 @@ +// run-rustfix +#![warn(clippy::iter_on_single_items)] +#![allow(clippy::iter_next_slice, clippy::redundant_clone)] + +fn array() { + assert_eq!([123].into_iter().next(), Some(123)); + assert_eq!([123].iter_mut().next(), Some(&mut 123)); + assert_eq!([123].iter().next(), Some(&123)); + assert_eq!(Some(123).into_iter().next(), Some(123)); + assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); + assert_eq!(Some(123).iter().next(), Some(&123)); + + // Don't trigger on non-iter methods + let _: Option<String> = Some("test".to_string()).clone(); + let _: [String; 1] = ["test".to_string()].clone(); + + // Don't trigger on match or if branches + let _ = match 123 { + 123 => [].iter(), + _ => ["test"].iter(), + }; + + let _ = if false { ["test"].iter() } else { [].iter() }; +} + +macro_rules! in_macros { + () => { + assert_eq!([123].into_iter().next(), Some(123)); + assert_eq!([123].iter_mut().next(), Some(&mut 123)); + assert_eq!([123].iter().next(), Some(&123)); + assert_eq!(Some(123).into_iter().next(), Some(123)); + assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); + assert_eq!(Some(123).iter().next(), Some(&123)); + }; +} + +// Don't trigger on a `Some` that isn't std's option +mod custom_option { + #[allow(unused)] + enum CustomOption { + Some(i32), + None, + } + + impl CustomOption { + fn iter(&self) {} + fn iter_mut(&mut self) {} + fn into_iter(self) {} + } + use CustomOption::*; + + pub fn custom_option() { + Some(3).iter(); + Some(3).iter_mut(); + Some(3).into_iter(); + } +} + +fn main() { + array(); + custom_option::custom_option(); + in_macros!(); +} diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.stderr b/src/tools/clippy/tests/ui/iter_on_single_items.stderr new file mode 100644 index 000000000..d6c547116 --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_on_single_items.stderr @@ -0,0 +1,40 @@ +error: `into_iter` call on a collection with only one item + --> $DIR/iter_on_single_items.rs:6:16 + | +LL | assert_eq!([123].into_iter().next(), Some(123)); + | ^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)` + | + = note: `-D clippy::iter-on-single-items` implied by `-D warnings` + +error: `iter_mut` call on a collection with only one item + --> $DIR/iter_on_single_items.rs:7:16 + | +LL | assert_eq!([123].iter_mut().next(), Some(&mut 123)); + | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)` + +error: `iter` call on a collection with only one item + --> $DIR/iter_on_single_items.rs:8:16 + | +LL | assert_eq!([123].iter().next(), Some(&123)); + | ^^^^^^^^^^^^ help: try: `std::iter::once(&123)` + +error: `into_iter` call on a collection with only one item + --> $DIR/iter_on_single_items.rs:9:16 + | +LL | assert_eq!(Some(123).into_iter().next(), Some(123)); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)` + +error: `iter_mut` call on a collection with only one item + --> $DIR/iter_on_single_items.rs:10:16 + | +LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); + | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)` + +error: `iter` call on a collection with only one item + --> $DIR/iter_on_single_items.rs:11:16 + | +LL | assert_eq!(Some(123).iter().next(), Some(&123)); + | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)` + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/iter_skip_next.fixed b/src/tools/clippy/tests/ui/iter_skip_next.fixed index 2db4c2bee..d56d623b5 100644 --- a/src/tools/clippy/tests/ui/iter_skip_next.fixed +++ b/src/tools/clippy/tests/ui/iter_skip_next.fixed @@ -2,7 +2,7 @@ // aux-build:option_helpers.rs #![warn(clippy::iter_skip_next)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] #![allow(clippy::iter_nth)] #![allow(unused_mut, dead_code)] diff --git a/src/tools/clippy/tests/ui/iter_skip_next.rs b/src/tools/clippy/tests/ui/iter_skip_next.rs index 692edb9ae..3ec5d1b82 100644 --- a/src/tools/clippy/tests/ui/iter_skip_next.rs +++ b/src/tools/clippy/tests/ui/iter_skip_next.rs @@ -2,7 +2,7 @@ // aux-build:option_helpers.rs #![warn(clippy::iter_skip_next)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] #![allow(clippy::iter_nth)] #![allow(unused_mut, dead_code)] diff --git a/src/tools/clippy/tests/ui/large_enum_variant.rs b/src/tools/clippy/tests/ui/large_enum_variant.rs index 23152a133..717009e4c 100644 --- a/src/tools/clippy/tests/ui/large_enum_variant.rs +++ b/src/tools/clippy/tests/ui/large_enum_variant.rs @@ -130,6 +130,30 @@ impl<T: Copy> Clone for SomeGenericPossiblyCopyEnum<T> { impl<T: Copy> Copy for SomeGenericPossiblyCopyEnum<T> {} +enum LargeEnumWithGenerics<T> { + Small, + Large((T, [u8; 512])), +} + +struct Foo<T> { + foo: T, +} + +enum WithGenerics { + Large([Foo<u64>; 64]), + Small(u8), +} + +enum PossiblyLargeEnumWithConst<const U: usize> { + SmallBuffer([u8; 4]), + MightyBuffer([u16; U]), +} + +enum LargeEnumOfConst { + Ok, + Error(PossiblyLargeEnumWithConst<256>), +} + fn main() { large_enum_variant!(); } diff --git a/src/tools/clippy/tests/ui/large_enum_variant.stderr b/src/tools/clippy/tests/ui/large_enum_variant.stderr index 024832726..c6ed97487 100644 --- a/src/tools/clippy/tests/ui/large_enum_variant.stderr +++ b/src/tools/clippy/tests/ui/large_enum_variant.stderr @@ -1,143 +1,177 @@ error: large size difference between variants - --> $DIR/large_enum_variant.rs:12:5 + --> $DIR/large_enum_variant.rs:10:1 | -LL | B([i32; 8000]), - | ^^^^^^^^^^^^^^ this variant is 32000 bytes +LL | / enum LargeEnum { +LL | | A(i32), + | | ------ the second-largest variant contains at least 4 bytes +LL | | B([i32; 8000]), + | | -------------- the largest variant contains at least 32000 bytes +LL | | } + | |_^ the entire enum is at least 32004 bytes | = note: `-D clippy::large-enum-variant` implied by `-D warnings` -note: and the second-largest variant is 4 bytes: - --> $DIR/large_enum_variant.rs:11:5 - | -LL | A(i32), - | ^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | B(Box<[i32; 8000]>), | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:36:5 - | -LL | ContainingLargeEnum(LargeEnum), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes + --> $DIR/large_enum_variant.rs:34:1 | -note: and the second-largest variant is 8 bytes: - --> $DIR/large_enum_variant.rs:35:5 +LL | / enum LargeEnum2 { +LL | | VariantOk(i32, u32), + | | ------------------- the second-largest variant contains at least 8 bytes +LL | | ContainingLargeEnum(LargeEnum), + | | ------------------------------ the largest variant contains at least 32004 bytes +LL | | } + | |_^ the entire enum is at least 32004 bytes | -LL | VariantOk(i32, u32), - | ^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | ContainingLargeEnum(Box<LargeEnum>), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:40:5 - | -LL | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70004 bytes + --> $DIR/large_enum_variant.rs:39:1 | -note: and the second-largest variant is 8 bytes: - --> $DIR/large_enum_variant.rs:42:5 +LL | / enum LargeEnum3 { +LL | | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), + | | --------------------------------------------------------- the largest variant contains at least 70004 bytes +LL | | VoidVariant, +LL | | StructLikeLittle { x: i32, y: i32 }, + | | ----------------------------------- the second-largest variant contains at least 8 bytes +LL | | } + | |_^ the entire enum is at least 70008 bytes | -LL | StructLikeLittle { x: i32, y: i32 }, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:47:5 + --> $DIR/large_enum_variant.rs:45:1 | -LL | StructLikeLarge { x: [i32; 8000], y: i32 }, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes +LL | / enum LargeEnum4 { +LL | | VariantOk(i32, u32), + | | ------------------- the second-largest variant contains at least 8 bytes +LL | | StructLikeLarge { x: [i32; 8000], y: i32 }, + | | ------------------------------------------ the largest variant contains at least 32004 bytes +LL | | } + | |_^ the entire enum is at least 32008 bytes | -note: and the second-largest variant is 8 bytes: - --> $DIR/large_enum_variant.rs:46:5 - | -LL | VariantOk(i32, u32), - | ^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:52:5 - | -LL | StructLikeLarge2 { x: [i32; 8000] }, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32000 bytes + --> $DIR/large_enum_variant.rs:50:1 | -note: and the second-largest variant is 8 bytes: - --> $DIR/large_enum_variant.rs:51:5 +LL | / enum LargeEnum5 { +LL | | VariantOk(i32, u32), + | | ------------------- the second-largest variant contains at least 8 bytes +LL | | StructLikeLarge2 { x: [i32; 8000] }, + | | ----------------------------------- the largest variant contains at least 32000 bytes +LL | | } + | |_^ the entire enum is at least 32004 bytes | -LL | VariantOk(i32, u32), - | ^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:68:5 - | -LL | B([u8; 1255]), - | ^^^^^^^^^^^^^ this variant is 1255 bytes + --> $DIR/large_enum_variant.rs:66:1 | -note: and the second-largest variant is 200 bytes: - --> $DIR/large_enum_variant.rs:69:5 +LL | / enum LargeEnum7 { +LL | | A, +LL | | B([u8; 1255]), + | | ------------- the largest variant contains at least 1255 bytes +LL | | C([u8; 200]), + | | ------------ the second-largest variant contains at least 200 bytes +LL | | } + | |_^ the entire enum is at least 1256 bytes | -LL | C([u8; 200]), - | ^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | B(Box<[u8; 1255]>), | ~~~~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:74:5 + --> $DIR/large_enum_variant.rs:72:1 | -LL | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70128 bytes +LL | / enum LargeEnum8 { +LL | | VariantOk(i32, u32), + | | ------------------- the second-largest variant contains at least 8 bytes +LL | | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), + | | ------------------------------------------------------------------------- the largest variant contains at least 70128 bytes +LL | | } + | |_^ the entire enum is at least 70132 bytes | -note: and the second-largest variant is 8 bytes: - --> $DIR/large_enum_variant.rs:73:5 - | -LL | VariantOk(i32, u32), - | ^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:79:5 + --> $DIR/large_enum_variant.rs:77:1 + | +LL | / enum LargeEnum9 { +LL | | A(Struct<()>), + | | ------------- the second-largest variant contains at least 4 bytes +LL | | B(Struct2), + | | ---------- the largest variant contains at least 32000 bytes +LL | | } + | |_^ the entire enum is at least 32004 bytes + | +help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Struct2), - | ^^^^^^^^^^ this variant is 32000 bytes +LL | B(Box<Struct2>), + | ~~~~~~~~~~~~ + +error: large size difference between variants + --> $DIR/large_enum_variant.rs:82:1 | -note: and the second-largest variant is 4 bytes: - --> $DIR/large_enum_variant.rs:78:5 +LL | / enum LargeEnumOk2<T> { +LL | | A(T), + | | ---- the second-largest variant contains at least 0 bytes +LL | | B(Struct2), + | | ---------- the largest variant contains at least 32000 bytes +LL | | } + | |_^ the entire enum is at least 32000 bytes | -LL | A(Struct<()>), - | ^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum | LL | B(Box<Struct2>), | ~~~~~~~~~~~~ error: large size difference between variants - --> $DIR/large_enum_variant.rs:104:5 + --> $DIR/large_enum_variant.rs:87:1 | -LL | B([u128; 4000]), - | ^^^^^^^^^^^^^^^ this variant is 64000 bytes +LL | / enum LargeEnumOk3<T> { +LL | | A(Struct<T>), + | | ------------ the second-largest variant contains at least 4 bytes +LL | | B(Struct2), + | | ---------- the largest variant contains at least 32000 bytes +LL | | } + | |_^ the entire enum is at least 32000 bytes + | +help: consider boxing the large fields to reduce the total size of the enum | -note: and the second-largest variant is 1 bytes: - --> $DIR/large_enum_variant.rs:103:5 +LL | B(Box<Struct2>), + | ~~~~~~~~~~~~ + +error: large size difference between variants + --> $DIR/large_enum_variant.rs:102:1 + | +LL | / enum CopyableLargeEnum { +LL | | A(bool), + | | ------- the second-largest variant contains at least 1 bytes +LL | | B([u128; 4000]), + | | --------------- the largest variant contains at least 64000 bytes +LL | | } + | |_^ the entire enum is at least 64008 bytes | -LL | A(bool), - | ^^^^^^^ note: boxing a variant would require the type no longer be `Copy` --> $DIR/large_enum_variant.rs:102:6 | @@ -150,16 +184,16 @@ LL | B([u128; 4000]), | ^^^^^^^^^^^^^^^ error: large size difference between variants - --> $DIR/large_enum_variant.rs:109:5 + --> $DIR/large_enum_variant.rs:107:1 | -LL | B([u128; 4000]), - | ^^^^^^^^^^^^^^^ this variant is 64000 bytes - | -note: and the second-largest variant is 1 bytes: - --> $DIR/large_enum_variant.rs:108:5 +LL | / enum ManuallyCopyLargeEnum { +LL | | A(bool), + | | ------- the second-largest variant contains at least 1 bytes +LL | | B([u128; 4000]), + | | --------------- the largest variant contains at least 64000 bytes +LL | | } + | |_^ the entire enum is at least 64008 bytes | -LL | A(bool), - | ^^^^^^^ note: boxing a variant would require the type no longer be `Copy` --> $DIR/large_enum_variant.rs:107:6 | @@ -172,16 +206,16 @@ LL | B([u128; 4000]), | ^^^^^^^^^^^^^^^ error: large size difference between variants - --> $DIR/large_enum_variant.rs:122:5 + --> $DIR/large_enum_variant.rs:120:1 | -LL | B([u64; 4000]), - | ^^^^^^^^^^^^^^ this variant is 32000 bytes - | -note: and the second-largest variant is 1 bytes: - --> $DIR/large_enum_variant.rs:121:5 +LL | / enum SomeGenericPossiblyCopyEnum<T> { +LL | | A(bool, std::marker::PhantomData<T>), + | | ------------------------------------ the second-largest variant contains at least 1 bytes +LL | | B([u64; 4000]), + | | -------------- the largest variant contains at least 32000 bytes +LL | | } + | |_^ the entire enum is at least 32008 bytes | -LL | A(bool, std::marker::PhantomData<T>), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: boxing a variant would require the type no longer be `Copy` --> $DIR/large_enum_variant.rs:120:6 | @@ -193,5 +227,53 @@ help: consider boxing the large fields to reduce the total size of the enum LL | B([u64; 4000]), | ^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: large size difference between variants + --> $DIR/large_enum_variant.rs:133:1 + | +LL | / enum LargeEnumWithGenerics<T> { +LL | | Small, + | | ----- the second-largest variant carries no data at all +LL | | Large((T, [u8; 512])), + | | --------------------- the largest variant contains at least 512 bytes +LL | | } + | |_^ the entire enum is at least 512 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | Large(Box<(T, [u8; 512])>), + | ~~~~~~~~~~~~~~~~~~~ + +error: large size difference between variants + --> $DIR/large_enum_variant.rs:142:1 + | +LL | / enum WithGenerics { +LL | | Large([Foo<u64>; 64]), + | | --------------------- the largest variant contains at least 512 bytes +LL | | Small(u8), + | | --------- the second-largest variant contains at least 1 bytes +LL | | } + | |_^ the entire enum is at least 520 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | Large(Box<[Foo<u64>; 64]>), + | ~~~~~~~~~~~~~~~~~~~ + +error: large size difference between variants + --> $DIR/large_enum_variant.rs:152:1 + | +LL | / enum LargeEnumOfConst { +LL | | Ok, + | | -- the second-largest variant carries no data at all +LL | | Error(PossiblyLargeEnumWithConst<256>), + | | -------------------------------------- the largest variant contains at least 514 bytes +LL | | } + | |_^ the entire enum is at least 514 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | Error(Box<PossiblyLargeEnumWithConst<256>>), + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/let_if_seq.rs b/src/tools/clippy/tests/ui/let_if_seq.rs index c5cb2eb1f..959567f68 100644 --- a/src/tools/clippy/tests/ui/let_if_seq.rs +++ b/src/tools/clippy/tests/ui/let_if_seq.rs @@ -2,7 +2,7 @@ unused_variables, unused_assignments, clippy::similar_names, - clippy::blacklisted_name, + clippy::disallowed_names, clippy::branches_sharing_code, clippy::needless_late_init )] diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed index d0bc640db..65598f1ea 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed +++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed @@ -17,7 +17,7 @@ fn main() { let c = Some(2); if !a.is_empty() && a.len() == 3 - && c != None + && c.is_some() && !a.is_empty() && a.len() == 3 && !a.is_empty() diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed index d0bc640db..65598f1ea 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed +++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed @@ -17,7 +17,7 @@ fn main() { let c = Some(2); if !a.is_empty() && a.len() == 3 - && c != None + && c.is_some() && !a.is_empty() && a.len() == 3 && !a.is_empty() diff --git a/src/tools/clippy/tests/ui/manual_assert.fixed b/src/tools/clippy/tests/ui/manual_assert.fixed index 6c2a25c37..a2393674f 100644 --- a/src/tools/clippy/tests/ui/manual_assert.fixed +++ b/src/tools/clippy/tests/ui/manual_assert.fixed @@ -11,7 +11,7 @@ fn main() { let c = Some(2); if !a.is_empty() && a.len() == 3 - && c != None + && c.is_some() && !a.is_empty() && a.len() == 3 && !a.is_empty() diff --git a/src/tools/clippy/tests/ui/manual_assert.rs b/src/tools/clippy/tests/ui/manual_assert.rs index 027747d83..4d2706dd6 100644 --- a/src/tools/clippy/tests/ui/manual_assert.rs +++ b/src/tools/clippy/tests/ui/manual_assert.rs @@ -17,7 +17,7 @@ fn main() { let c = Some(2); if !a.is_empty() && a.len() == 3 - && c != None + && c.is_some() && !a.is_empty() && a.len() == 3 && !a.is_empty() diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed new file mode 100644 index 000000000..0fa776b7b --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed @@ -0,0 +1,27 @@ +// run-rustfix +#![warn(clippy::manual_instant_elapsed)] +#![allow(clippy::unnecessary_operation)] +#![allow(unused_variables)] +#![allow(unused_must_use)] + +use std::time::Instant; + +fn main() { + let prev_instant = Instant::now(); + + { + // don't influence + let another_instant = Instant::now(); + } + + let duration = prev_instant.elapsed(); + + // don't catch + let duration = prev_instant.elapsed(); + + Instant::now() - duration; + + let ref_to_instant = &Instant::now(); + + (*ref_to_instant).elapsed(); // to ensure parens are added correctly +} diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs new file mode 100644 index 000000000..5b11b8453 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs @@ -0,0 +1,27 @@ +// run-rustfix +#![warn(clippy::manual_instant_elapsed)] +#![allow(clippy::unnecessary_operation)] +#![allow(unused_variables)] +#![allow(unused_must_use)] + +use std::time::Instant; + +fn main() { + let prev_instant = Instant::now(); + + { + // don't influence + let another_instant = Instant::now(); + } + + let duration = Instant::now() - prev_instant; + + // don't catch + let duration = prev_instant.elapsed(); + + Instant::now() - duration; + + let ref_to_instant = &Instant::now(); + + Instant::now() - *ref_to_instant; // to ensure parens are added correctly +} diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr new file mode 100644 index 000000000..5537f5642 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr @@ -0,0 +1,16 @@ +error: manual implementation of `Instant::elapsed` + --> $DIR/manual_instant_elapsed.rs:17:20 + | +LL | let duration = Instant::now() - prev_instant; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `prev_instant.elapsed()` + | + = note: `-D clippy::manual-instant-elapsed` implied by `-D warnings` + +error: manual implementation of `Instant::elapsed` + --> $DIR/manual_instant_elapsed.rs:26:5 + | +LL | Instant::now() - *ref_to_instant; // to ensure parens are added correctly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*ref_to_instant).elapsed()` + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/manual_ok_or.fixed b/src/tools/clippy/tests/ui/manual_ok_or.fixed index 887a97d7a..d864f8554 100644 --- a/src/tools/clippy/tests/ui/manual_ok_or.fixed +++ b/src/tools/clippy/tests/ui/manual_ok_or.fixed @@ -1,6 +1,6 @@ // run-rustfix #![warn(clippy::manual_ok_or)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] #![allow(clippy::redundant_closure)] #![allow(dead_code)] #![allow(unused_must_use)] diff --git a/src/tools/clippy/tests/ui/manual_ok_or.rs b/src/tools/clippy/tests/ui/manual_ok_or.rs index 3c99872f5..626476846 100644 --- a/src/tools/clippy/tests/ui/manual_ok_or.rs +++ b/src/tools/clippy/tests/ui/manual_ok_or.rs @@ -1,6 +1,6 @@ // run-rustfix #![warn(clippy::manual_ok_or)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] #![allow(clippy::redundant_closure)] #![allow(dead_code)] #![allow(unused_must_use)] diff --git a/src/tools/clippy/tests/ui/manual_string_new.fixed b/src/tools/clippy/tests/ui/manual_string_new.fixed new file mode 100644 index 000000000..a376411bf --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_string_new.fixed @@ -0,0 +1,63 @@ +// run-rustfix + +#![warn(clippy::manual_string_new)] + +macro_rules! create_strings_from_macro { + // When inside a macro, nothing should warn to prevent false positives. + ($some_str:expr) => { + let _: String = $some_str.into(); + let _ = $some_str.to_string(); + }; +} + +fn main() { + // Method calls + let _ = String::new(); + let _ = "no warning".to_string(); + + let _ = String::new(); + let _ = "no warning".to_owned(); + + let _: String = String::new(); + let _: String = "no warning".into(); + + let _: SomeOtherStruct = "no warning".into(); + let _: SomeOtherStruct = "".into(); // No warning too. We are not converting into String. + + // Calls + let _ = String::new(); + let _ = String::new(); + let _ = String::from("no warning"); + let _ = SomeOtherStruct::from("no warning"); + let _ = SomeOtherStruct::from(""); // Again: no warning. + + let _ = String::new(); + let _ = String::try_from("no warning").unwrap(); + let _ = String::try_from("no warning").expect("this should not warn"); + let _ = SomeOtherStruct::try_from("no warning").unwrap(); + let _ = SomeOtherStruct::try_from("").unwrap(); // Again: no warning. + + let _: String = String::new(); + let _: String = From::from("no warning"); + let _: SomeOtherStruct = From::from("no warning"); + let _: SomeOtherStruct = From::from(""); // Again: no warning. + + let _: String = String::new(); + let _: String = TryFrom::try_from("no warning").unwrap(); + let _: String = TryFrom::try_from("no warning").expect("this should not warn"); + let _: String = String::new(); + let _: SomeOtherStruct = TryFrom::try_from("no_warning").unwrap(); + let _: SomeOtherStruct = TryFrom::try_from("").unwrap(); // Again: no warning. + + // Macros (never warn) + create_strings_from_macro!(""); + create_strings_from_macro!("Hey"); +} + +struct SomeOtherStruct {} + +impl From<&str> for SomeOtherStruct { + fn from(_value: &str) -> Self { + Self {} + } +} diff --git a/src/tools/clippy/tests/ui/manual_string_new.rs b/src/tools/clippy/tests/ui/manual_string_new.rs new file mode 100644 index 000000000..6bfc52fb1 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_string_new.rs @@ -0,0 +1,63 @@ +// run-rustfix + +#![warn(clippy::manual_string_new)] + +macro_rules! create_strings_from_macro { + // When inside a macro, nothing should warn to prevent false positives. + ($some_str:expr) => { + let _: String = $some_str.into(); + let _ = $some_str.to_string(); + }; +} + +fn main() { + // Method calls + let _ = "".to_string(); + let _ = "no warning".to_string(); + + let _ = "".to_owned(); + let _ = "no warning".to_owned(); + + let _: String = "".into(); + let _: String = "no warning".into(); + + let _: SomeOtherStruct = "no warning".into(); + let _: SomeOtherStruct = "".into(); // No warning too. We are not converting into String. + + // Calls + let _ = String::from(""); + let _ = <String>::from(""); + let _ = String::from("no warning"); + let _ = SomeOtherStruct::from("no warning"); + let _ = SomeOtherStruct::from(""); // Again: no warning. + + let _ = String::try_from("").unwrap(); + let _ = String::try_from("no warning").unwrap(); + let _ = String::try_from("no warning").expect("this should not warn"); + let _ = SomeOtherStruct::try_from("no warning").unwrap(); + let _ = SomeOtherStruct::try_from("").unwrap(); // Again: no warning. + + let _: String = From::from(""); + let _: String = From::from("no warning"); + let _: SomeOtherStruct = From::from("no warning"); + let _: SomeOtherStruct = From::from(""); // Again: no warning. + + let _: String = TryFrom::try_from("").unwrap(); + let _: String = TryFrom::try_from("no warning").unwrap(); + let _: String = TryFrom::try_from("no warning").expect("this should not warn"); + let _: String = TryFrom::try_from("").expect("this should warn"); + let _: SomeOtherStruct = TryFrom::try_from("no_warning").unwrap(); + let _: SomeOtherStruct = TryFrom::try_from("").unwrap(); // Again: no warning. + + // Macros (never warn) + create_strings_from_macro!(""); + create_strings_from_macro!("Hey"); +} + +struct SomeOtherStruct {} + +impl From<&str> for SomeOtherStruct { + fn from(_value: &str) -> Self { + Self {} + } +} diff --git a/src/tools/clippy/tests/ui/manual_string_new.stderr b/src/tools/clippy/tests/ui/manual_string_new.stderr new file mode 100644 index 000000000..e5ecfc619 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_string_new.stderr @@ -0,0 +1,58 @@ +error: empty String is being created manually + --> $DIR/manual_string_new.rs:15:13 + | +LL | let _ = "".to_string(); + | ^^^^^^^^^^^^^^ help: consider using: `String::new()` + | + = note: `-D clippy::manual-string-new` implied by `-D warnings` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:18:13 + | +LL | let _ = "".to_owned(); + | ^^^^^^^^^^^^^ help: consider using: `String::new()` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:21:21 + | +LL | let _: String = "".into(); + | ^^^^^^^^^ help: consider using: `String::new()` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:28:13 + | +LL | let _ = String::from(""); + | ^^^^^^^^^^^^^^^^ help: consider using: `String::new()` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:29:13 + | +LL | let _ = <String>::from(""); + | ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:34:13 + | +LL | let _ = String::try_from("").unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:40:21 + | +LL | let _: String = From::from(""); + | ^^^^^^^^^^^^^^ help: consider using: `String::new()` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:45:21 + | +LL | let _: String = TryFrom::try_from("").unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` + +error: empty String is being created manually + --> $DIR/manual_string_new.rs:48:21 + | +LL | let _: String = TryFrom::try_from("").expect("this should warn"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` + +error: aborting due to 9 previous errors + diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed index 1ccbfda64..95ca571d0 100644 --- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed +++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed @@ -167,4 +167,29 @@ fn main() { _ => false, }; } + + let x = ' '; + // ignore if match block contains comment + let _line_comments = match x { + // numbers are bad! + '1' | '2' | '3' => true, + // spaces are very important to be true. + ' ' => true, + // as are dots + '.' => true, + _ => false, + }; + + let _block_comments = match x { + /* numbers are bad! + */ + '1' | '2' | '3' => true, + /* spaces are very important to be true. + */ + ' ' => true, + /* as are dots + */ + '.' => true, + _ => false, + }; } diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs index a49991f59..3b9c8cada 100644 --- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs +++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs @@ -208,4 +208,29 @@ fn main() { _ => false, }; } + + let x = ' '; + // ignore if match block contains comment + let _line_comments = match x { + // numbers are bad! + '1' | '2' | '3' => true, + // spaces are very important to be true. + ' ' => true, + // as are dots + '.' => true, + _ => false, + }; + + let _block_comments = match x { + /* numbers are bad! + */ + '1' | '2' | '3' => true, + /* spaces are very important to be true. + */ + ' ' => true, + /* as are dots + */ + '.' => true, + _ => false, + }; } diff --git a/src/tools/clippy/tests/ui/match_same_arms2.rs b/src/tools/clippy/tests/ui/match_same_arms2.rs index 7aba5b447..61793e80c 100644 --- a/src/tools/clippy/tests/ui/match_same_arms2.rs +++ b/src/tools/clippy/tests/ui/match_same_arms2.rs @@ -1,5 +1,5 @@ #![warn(clippy::match_same_arms)] -#![allow(clippy::blacklisted_name, clippy::diverging_sub_expression)] +#![allow(clippy::disallowed_names, clippy::diverging_sub_expression)] fn bar<T>(_: T) {} fn foo() -> bool { diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr index 2a4012039..2d66daea8 100644 --- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr +++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr @@ -5,7 +5,7 @@ LL | Err(_) => panic!("err"), | ^^^^^^ | = note: `-D clippy::match-wild-err-arm` implied by `-D warnings` - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors --> $DIR/match_wild_err_arm.rs:20:9 @@ -13,7 +13,7 @@ error: `Err(_)` matches all errors LL | Err(_) => panic!(), | ^^^^^^ | - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors --> $DIR/match_wild_err_arm.rs:26:9 @@ -21,7 +21,7 @@ error: `Err(_)` matches all errors LL | Err(_) => { | ^^^^^^ | - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_e)` matches all errors --> $DIR/match_wild_err_arm.rs:34:9 @@ -29,7 +29,7 @@ error: `Err(_e)` matches all errors LL | Err(_e) => panic!(), | ^^^^^^^ | - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr index 2a4012039..2d66daea8 100644 --- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr +++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr @@ -5,7 +5,7 @@ LL | Err(_) => panic!("err"), | ^^^^^^ | = note: `-D clippy::match-wild-err-arm` implied by `-D warnings` - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors --> $DIR/match_wild_err_arm.rs:20:9 @@ -13,7 +13,7 @@ error: `Err(_)` matches all errors LL | Err(_) => panic!(), | ^^^^^^ | - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors --> $DIR/match_wild_err_arm.rs:26:9 @@ -21,7 +21,7 @@ error: `Err(_)` matches all errors LL | Err(_) => { | ^^^^^^ | - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_e)` matches all errors --> $DIR/match_wild_err_arm.rs:34:9 @@ -29,7 +29,7 @@ error: `Err(_e)` matches all errors LL | Err(_e) => panic!(), | ^^^^^^^ | - = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable + = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/methods.rs b/src/tools/clippy/tests/ui/methods.rs index 1970c2eae..6f22366ea 100644 --- a/src/tools/clippy/tests/ui/methods.rs +++ b/src/tools/clippy/tests/ui/methods.rs @@ -2,7 +2,7 @@ #![warn(clippy::all, clippy::pedantic)] #![allow( - clippy::blacklisted_name, + clippy::disallowed_names, clippy::default_trait_access, clippy::missing_docs_in_private_items, clippy::missing_safety_doc, diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs index 8c0da84d8..40c1fcae1 100644 --- a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs +++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs @@ -1,5 +1,5 @@ #![warn(clippy::mismatching_type_param_order)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] fn main() { struct Foo<A, B> { diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs index aa60d0504..b950248ef 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -3,12 +3,16 @@ //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. // aux-build:helper.rs +// aux-build:../../auxiliary/proc_macro_with_span.rs #![warn(clippy::missing_const_for_fn)] #![feature(start)] #![feature(custom_inner_attributes)] extern crate helper; +extern crate proc_macro_with_span; + +use proc_macro_with_span::with_span; struct Game; @@ -119,3 +123,8 @@ mod const_fn_stabilized_after_msrv { byte.is_ascii_digit(); } } + +with_span! { + span + fn dont_check_in_proc_macro() {} +} diff --git a/src/tools/clippy/tests/ui/missing-doc.rs b/src/tools/clippy/tests/ui/missing_doc.rs index 6e2e710e2..29cc026a8 100644 --- a/src/tools/clippy/tests/ui/missing-doc.rs +++ b/src/tools/clippy/tests/ui/missing_doc.rs @@ -1,3 +1,5 @@ +// aux-build: proc_macro_with_span.rs + #![warn(clippy::missing_docs_in_private_items)] // When denying at the crate level, be sure to not get random warnings from the // injected intrinsics by the compiler. @@ -5,6 +7,9 @@ //! Some garbage docs for the crate here #![doc = "More garbage"] +extern crate proc_macro_with_span; + +use proc_macro_with_span::with_span; use std::arch::global_asm; type Typedef = String; @@ -100,3 +105,11 @@ fn main() {} // Ensure global asm doesn't require documentation. global_asm! { "" } + +// Don't lint proc macro output with an unexpected span. +with_span!(span pub struct FooPm { pub field: u32}); +with_span!(span pub struct FooPm2;); +with_span!(span pub enum FooPm3 { A, B(u32), C { field: u32 }}); +with_span!(span pub fn foo_pm() {}); +with_span!(span pub static FOO_PM: u32 = 0;); +with_span!(span pub const FOO2_PM: u32 = 0;); diff --git a/src/tools/clippy/tests/ui/missing-doc.stderr b/src/tools/clippy/tests/ui/missing_doc.stderr index a876dc078..6c8e66f46 100644 --- a/src/tools/clippy/tests/ui/missing-doc.stderr +++ b/src/tools/clippy/tests/ui/missing_doc.stderr @@ -1,5 +1,5 @@ error: missing documentation for a type alias - --> $DIR/missing-doc.rs:10:1 + --> $DIR/missing_doc.rs:15:1 | LL | type Typedef = String; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,37 +7,37 @@ LL | type Typedef = String; = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` error: missing documentation for a type alias - --> $DIR/missing-doc.rs:11:1 + --> $DIR/missing_doc.rs:16:1 | LL | pub type PubTypedef = String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a module - --> $DIR/missing-doc.rs:13:1 + --> $DIR/missing_doc.rs:18:1 | LL | mod module_no_dox {} | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a module - --> $DIR/missing-doc.rs:14:1 + --> $DIR/missing_doc.rs:19:1 | LL | pub mod pub_module_no_dox {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/missing-doc.rs:18:1 + --> $DIR/missing_doc.rs:23:1 | LL | pub fn foo2() {} | ^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/missing-doc.rs:19:1 + --> $DIR/missing_doc.rs:24:1 | LL | fn foo3() {} | ^^^^^^^^^^^^ error: missing documentation for an enum - --> $DIR/missing-doc.rs:33:1 + --> $DIR/missing_doc.rs:38:1 | LL | / enum Baz { LL | | BazA { a: isize, b: isize }, @@ -46,31 +46,31 @@ LL | | } | |_^ error: missing documentation for a variant - --> $DIR/missing-doc.rs:34:5 + --> $DIR/missing_doc.rs:39:5 | LL | BazA { a: isize, b: isize }, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a struct field - --> $DIR/missing-doc.rs:34:12 + --> $DIR/missing_doc.rs:39:12 | LL | BazA { a: isize, b: isize }, | ^^^^^^^^ error: missing documentation for a struct field - --> $DIR/missing-doc.rs:34:22 + --> $DIR/missing_doc.rs:39:22 | LL | BazA { a: isize, b: isize }, | ^^^^^^^^ error: missing documentation for a variant - --> $DIR/missing-doc.rs:35:5 + --> $DIR/missing_doc.rs:40:5 | LL | BarB, | ^^^^ error: missing documentation for an enum - --> $DIR/missing-doc.rs:38:1 + --> $DIR/missing_doc.rs:43:1 | LL | / pub enum PubBaz { LL | | PubBazA { a: isize }, @@ -78,43 +78,43 @@ LL | | } | |_^ error: missing documentation for a variant - --> $DIR/missing-doc.rs:39:5 + --> $DIR/missing_doc.rs:44:5 | LL | PubBazA { a: isize }, | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a struct field - --> $DIR/missing-doc.rs:39:15 + --> $DIR/missing_doc.rs:44:15 | LL | PubBazA { a: isize }, | ^^^^^^^^ error: missing documentation for a constant - --> $DIR/missing-doc.rs:59:1 + --> $DIR/missing_doc.rs:64:1 | LL | const FOO: u32 = 0; | ^^^^^^^^^^^^^^^^^^^ error: missing documentation for a constant - --> $DIR/missing-doc.rs:66:1 + --> $DIR/missing_doc.rs:71:1 | LL | pub const FOO4: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static - --> $DIR/missing-doc.rs:68:1 + --> $DIR/missing_doc.rs:73:1 | LL | static BAR: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static - --> $DIR/missing-doc.rs:75:1 + --> $DIR/missing_doc.rs:80:1 | LL | pub static BAR4: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a module - --> $DIR/missing-doc.rs:77:1 + --> $DIR/missing_doc.rs:82:1 | LL | / mod internal_impl { LL | | /// dox @@ -126,31 +126,31 @@ LL | | } | |_^ error: missing documentation for a function - --> $DIR/missing-doc.rs:80:5 + --> $DIR/missing_doc.rs:85:5 | LL | pub fn undocumented1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/missing-doc.rs:81:5 + --> $DIR/missing_doc.rs:86:5 | LL | pub fn undocumented2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/missing-doc.rs:82:5 + --> $DIR/missing_doc.rs:87:5 | LL | fn undocumented3() {} | ^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/missing-doc.rs:87:9 + --> $DIR/missing_doc.rs:92:9 | LL | pub fn also_undocumented1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/missing-doc.rs:88:9 + --> $DIR/missing_doc.rs:93:9 | LL | fn also_undocumented2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/missing-doc-crate.rs b/src/tools/clippy/tests/ui/missing_doc_crate.rs index e00c7fbfe..e00c7fbfe 100644 --- a/src/tools/clippy/tests/ui/missing-doc-crate.rs +++ b/src/tools/clippy/tests/ui/missing_doc_crate.rs diff --git a/src/tools/clippy/tests/ui/missing-doc-crate-missing.rs b/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs index 51fd57df8..51fd57df8 100644 --- a/src/tools/clippy/tests/ui/missing-doc-crate-missing.rs +++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs diff --git a/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr index d56c5cc4c..19516bf5f 100644 --- a/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr +++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr @@ -1,5 +1,5 @@ error: missing documentation for the crate - --> $DIR/missing-doc-crate-missing.rs:1:1 + --> $DIR/missing_doc_crate_missing.rs:1:1 | LL | / #![warn(clippy::missing_docs_in_private_items)] LL | | diff --git a/src/tools/clippy/tests/ui/missing-doc-impl.rs b/src/tools/clippy/tests/ui/missing_doc_impl.rs index d5724bf66..0396d1193 100644 --- a/src/tools/clippy/tests/ui/missing-doc-impl.rs +++ b/src/tools/clippy/tests/ui/missing_doc_impl.rs @@ -1,3 +1,5 @@ +// aux-build: proc_macro_with_span.rs + #![warn(clippy::missing_docs_in_private_items)] #![allow(dead_code)] #![feature(associated_type_defaults)] @@ -5,6 +7,9 @@ //! Some garbage docs for the crate here #![doc = "More garbage"] +extern crate proc_macro_with_span; +use proc_macro_with_span::with_span; + struct Foo { a: isize, b: isize, @@ -90,3 +95,13 @@ impl F for Foo { } fn main() {} + +// don't lint proc macro output +with_span!(span + pub struct FooPm; + impl FooPm { + pub fn foo() {} + pub const fn bar() {} + pub const X: u32 = 0; + } +); diff --git a/src/tools/clippy/tests/ui/missing-doc-impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr index bda63d66a..f22fa19db 100644 --- a/src/tools/clippy/tests/ui/missing-doc-impl.stderr +++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr @@ -1,5 +1,5 @@ error: missing documentation for a struct - --> $DIR/missing-doc-impl.rs:8:1 + --> $DIR/missing_doc_impl.rs:13:1 | LL | / struct Foo { LL | | a: isize, @@ -10,19 +10,19 @@ LL | | } = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` error: missing documentation for a struct field - --> $DIR/missing-doc-impl.rs:9:5 + --> $DIR/missing_doc_impl.rs:14:5 | LL | a: isize, | ^^^^^^^^ error: missing documentation for a struct field - --> $DIR/missing-doc-impl.rs:10:5 + --> $DIR/missing_doc_impl.rs:15:5 | LL | b: isize, | ^^^^^^^^ error: missing documentation for a struct - --> $DIR/missing-doc-impl.rs:13:1 + --> $DIR/missing_doc_impl.rs:18:1 | LL | / pub struct PubFoo { LL | | pub a: isize, @@ -31,19 +31,19 @@ LL | | } | |_^ error: missing documentation for a struct field - --> $DIR/missing-doc-impl.rs:14:5 + --> $DIR/missing_doc_impl.rs:19:5 | LL | pub a: isize, | ^^^^^^^^^^^^ error: missing documentation for a struct field - --> $DIR/missing-doc-impl.rs:15:5 + --> $DIR/missing_doc_impl.rs:20:5 | LL | b: isize, | ^^^^^^^^ error: missing documentation for a trait - --> $DIR/missing-doc-impl.rs:38:1 + --> $DIR/missing_doc_impl.rs:43:1 | LL | / pub trait C { LL | | fn foo(&self); @@ -52,31 +52,31 @@ LL | | } | |_^ error: missing documentation for an associated function - --> $DIR/missing-doc-impl.rs:39:5 + --> $DIR/missing_doc_impl.rs:44:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/missing-doc-impl.rs:40:5 + --> $DIR/missing_doc_impl.rs:45:5 | LL | fn foo_with_impl(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated type - --> $DIR/missing-doc-impl.rs:50:5 + --> $DIR/missing_doc_impl.rs:55:5 | LL | type AssociatedType; | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated type - --> $DIR/missing-doc-impl.rs:51:5 + --> $DIR/missing_doc_impl.rs:56:5 | LL | type AssociatedTypeDef = Self; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/missing-doc-impl.rs:62:5 + --> $DIR/missing_doc_impl.rs:67:5 | LL | / pub fn new() -> Self { LL | | Foo { a: 0, b: 0 } @@ -84,19 +84,19 @@ LL | | } | |_____^ error: missing documentation for an associated function - --> $DIR/missing-doc-impl.rs:65:5 + --> $DIR/missing_doc_impl.rs:70:5 | LL | fn bar() {} | ^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/missing-doc-impl.rs:69:5 + --> $DIR/missing_doc_impl.rs:74:5 | LL | pub fn foo() {} | ^^^^^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/missing-doc-impl.rs:73:5 + --> $DIR/missing_doc_impl.rs:78:5 | LL | / fn foo2() -> u32 { LL | | 1 diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed index a7b36d53c..becb9562a 100644 --- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed +++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: proc_macro_with_span.rs #![allow( dead_code, @@ -9,6 +10,9 @@ clippy::unusual_byte_groupings )] +extern crate proc_macro_with_span; +use proc_macro_with_span::with_span; + fn main() { let fail14 = 2_i32; let fail15 = 4_i64; @@ -40,4 +44,6 @@ fn main() { let ok38 = 124_64.0; let _ = 1.123_45E1_f32; + + let _ = with_span!(1 2_u32); } diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs index c97b31965..ee841bcd7 100644 --- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs +++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: proc_macro_with_span.rs #![allow( dead_code, @@ -9,6 +10,9 @@ clippy::unusual_byte_groupings )] +extern crate proc_macro_with_span; +use proc_macro_with_span::with_span; + fn main() { let fail14 = 2_32; let fail15 = 4_64; @@ -40,4 +44,6 @@ fn main() { let ok38 = 124_64.0; let _ = 1.12345E1_32; + + let _ = with_span!(1 2_u32); } diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr index fb761d9bd..ef8e6a33d 100644 --- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr +++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr @@ -1,5 +1,5 @@ error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:13:18 + --> $DIR/mistyped_literal_suffix.rs:17:18 | LL | let fail14 = 2_32; | ^^^^ help: did you mean to write: `2_i32` @@ -7,91 +7,91 @@ LL | let fail14 = 2_32; = note: `#[deny(clippy::mistyped_literal_suffixes)]` on by default error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:14:18 + --> $DIR/mistyped_literal_suffix.rs:18:18 | LL | let fail15 = 4_64; | ^^^^ help: did you mean to write: `4_i64` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:15:18 + --> $DIR/mistyped_literal_suffix.rs:19:18 | LL | let fail16 = 7_8; // | ^^^ help: did you mean to write: `7_i8` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:16:18 + --> $DIR/mistyped_literal_suffix.rs:20:18 | LL | let fail17 = 23_16; // | ^^^^^ help: did you mean to write: `23_i16` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:19:18 + --> $DIR/mistyped_literal_suffix.rs:23:18 | LL | let fail20 = 2__8; // | ^^^^ help: did you mean to write: `2_i8` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:20:18 + --> $DIR/mistyped_literal_suffix.rs:24:18 | LL | let fail21 = 4___16; // | ^^^^^^ help: did you mean to write: `4_i16` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:23:18 + --> $DIR/mistyped_literal_suffix.rs:27:18 | LL | let fail25 = 1E2_32; | ^^^^^^ help: did you mean to write: `1E2_f32` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:24:18 + --> $DIR/mistyped_literal_suffix.rs:28:18 | LL | let fail26 = 43E7_64; | ^^^^^^^ help: did you mean to write: `43E7_f64` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:25:18 + --> $DIR/mistyped_literal_suffix.rs:29:18 | LL | let fail27 = 243E17_32; | ^^^^^^^^^ help: did you mean to write: `243E17_f32` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:26:18 + --> $DIR/mistyped_literal_suffix.rs:30:18 | LL | let fail28 = 241251235E723_64; | ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:30:18 + --> $DIR/mistyped_literal_suffix.rs:34:18 | LL | let fail30 = 127_8; // should be i8 | ^^^^^ help: did you mean to write: `127_i8` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:31:18 + --> $DIR/mistyped_literal_suffix.rs:35:18 | LL | let fail31 = 240_8; // should be u8 | ^^^^^ help: did you mean to write: `240_u8` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:33:18 + --> $DIR/mistyped_literal_suffix.rs:37:18 | LL | let fail33 = 0x1234_16; | ^^^^^^^^^ help: did you mean to write: `0x1234_i16` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:34:18 + --> $DIR/mistyped_literal_suffix.rs:38:18 | LL | let fail34 = 0xABCD_16; | ^^^^^^^^^ help: did you mean to write: `0xABCD_u16` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:36:18 + --> $DIR/mistyped_literal_suffix.rs:40:18 | LL | let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64` error: mistyped literal suffix - --> $DIR/mistyped_literal_suffix.rs:42:13 + --> $DIR/mistyped_literal_suffix.rs:46:13 | LL | let _ = 1.12345E1_32; | ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32` diff --git a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs index 7640057ab..6efc7657e 100644 --- a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs @@ -4,7 +4,7 @@ unused_variables, clippy::no_effect, dead_code, - clippy::blacklisted_name + clippy::disallowed_names )] fn main() { let mut x = 0; diff --git a/src/tools/clippy/tests/ui/multi_assignments.rs b/src/tools/clippy/tests/ui/multi_assignments.rs new file mode 100644 index 000000000..b186bf8bb --- /dev/null +++ b/src/tools/clippy/tests/ui/multi_assignments.rs @@ -0,0 +1,9 @@ +#![warn(clippy::multi_assignments)] +fn main() { + let (mut a, mut b, mut c, mut d) = ((), (), (), ()); + a = b = c; + a = b = c = d; + a = b = { c }; + a = { b = c }; + a = (b = c); +} diff --git a/src/tools/clippy/tests/ui/multi_assignments.stderr b/src/tools/clippy/tests/ui/multi_assignments.stderr new file mode 100644 index 000000000..d6c42bb69 --- /dev/null +++ b/src/tools/clippy/tests/ui/multi_assignments.stderr @@ -0,0 +1,40 @@ +error: assignments don't nest intuitively + --> $DIR/multi_assignments.rs:4:5 + | +LL | a = b = c; + | ^^^^^^^^^ + | + = note: `-D clippy::multi-assignments` implied by `-D warnings` + +error: assignments don't nest intuitively + --> $DIR/multi_assignments.rs:5:5 + | +LL | a = b = c = d; + | ^^^^^^^^^^^^^ + +error: assignments don't nest intuitively + --> $DIR/multi_assignments.rs:5:9 + | +LL | a = b = c = d; + | ^^^^^^^^^ + +error: assignments don't nest intuitively + --> $DIR/multi_assignments.rs:6:5 + | +LL | a = b = { c }; + | ^^^^^^^^^^^^^ + +error: assignments don't nest intuitively + --> $DIR/multi_assignments.rs:7:5 + | +LL | a = { b = c }; + | ^^^^^^^^^^^^^ + +error: assignments don't nest intuitively + --> $DIR/multi_assignments.rs:8:5 + | +LL | a = (b = c); + | ^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed index 36bc52e33..ecad10a82 100644 --- a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed +++ b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed @@ -18,4 +18,11 @@ fn no_owned_mutex_lock() { *value += 1; } +fn issue9415() { + let mut arc_mutex = Arc::new(Mutex::new(42_u8)); + let arc_mutex: &mut Arc<Mutex<u8>> = &mut arc_mutex; + let mut guard = arc_mutex.lock().unwrap(); + *guard += 1; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.rs b/src/tools/clippy/tests/ui/mut_mutex_lock.rs index ea60df5ae..f2b1d6fbf 100644 --- a/src/tools/clippy/tests/ui/mut_mutex_lock.rs +++ b/src/tools/clippy/tests/ui/mut_mutex_lock.rs @@ -18,4 +18,11 @@ fn no_owned_mutex_lock() { *value += 1; } +fn issue9415() { + let mut arc_mutex = Arc::new(Mutex::new(42_u8)); + let arc_mutex: &mut Arc<Mutex<u8>> = &mut arc_mutex; + let mut guard = arc_mutex.lock().unwrap(); + *guard += 1; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed index bfd2725ec..8cf93bd24 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.fixed +++ b/src/tools/clippy/tests/ui/needless_borrow.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![feature(lint_reasons)] +#![feature(custom_inner_attributes, lint_reasons)] #[warn(clippy::all, clippy::needless_borrow)] #[allow(unused_variables, clippy::unnecessary_mut_passed)] @@ -127,6 +127,20 @@ fn main() { 0 } } + + let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap(); + let _ = std::path::Path::new(".").join("."); + deref_target_is_x(X); + multiple_constraints([[""]]); + multiple_constraints_normalizes_to_same(X, X); + let _ = Some("").unwrap_or(""); + + only_sized(&""); // Don't lint. `Sized` is only bound + let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound + let _ = Box::new(&""); // Don't lint. Type parameter appears in return type + ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter + refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't + multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments } #[allow(clippy::needless_borrowed_reference)] @@ -183,3 +197,104 @@ mod issue9160 { } } } + +#[derive(Clone, Copy)] +struct X; + +impl std::ops::Deref for X { + type Target = X; + fn deref(&self) -> &Self::Target { + self + } +} + +fn deref_target_is_x<T>(_: T) +where + T: std::ops::Deref<Target = X>, +{ +} + +fn multiple_constraints<T, U, V, X, Y>(_: T) +where + T: IntoIterator<Item = U> + IntoIterator<Item = X>, + U: IntoIterator<Item = V>, + V: AsRef<str>, + X: IntoIterator<Item = Y>, + Y: AsRef<std::ffi::OsStr>, +{ +} + +fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V) +where + T: std::ops::Deref<Target = U>, + U: std::ops::Deref<Target = V>, +{ +} + +fn only_sized<T>(_: T) {} + +fn ref_as_ref_path<T: 'static>(_: &'static T) +where + &'static T: AsRef<std::path::Path>, +{ +} + +trait RefsOnly { + type Referent; +} + +impl<T> RefsOnly for &T { + type Referent = T; +} + +fn refs_only<T, U>(_: T) +where + T: RefsOnly<Referent = U>, +{ +} + +fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U) +where + T: IntoIterator<Item = U>, + U: IntoIterator<Item = V>, + V: AsRef<str>, +{ +} + +// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321 +#[allow(dead_code)] +mod copyable_iterator { + #[derive(Clone, Copy)] + struct Iter; + impl Iterator for Iter { + type Item = (); + fn next(&mut self) -> Option<Self::Item> { + None + } + } + fn takes_iter(_: impl Iterator) {} + fn dont_warn(mut x: Iter) { + takes_iter(&mut x); + } + fn warn(mut x: &mut Iter) { + takes_iter(&mut x) + } +} + +mod under_msrv { + #![allow(dead_code)] + #![clippy::msrv = "1.52.0"] + + fn foo() { + let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + } +} + +mod meets_msrv { + #![allow(dead_code)] + #![clippy::msrv = "1.53.0"] + + fn foo() { + let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap(); + } +} diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs index c457d8c54..fd9b2a11d 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.rs +++ b/src/tools/clippy/tests/ui/needless_borrow.rs @@ -1,6 +1,6 @@ // run-rustfix -#![feature(lint_reasons)] +#![feature(custom_inner_attributes, lint_reasons)] #[warn(clippy::all, clippy::needless_borrow)] #[allow(unused_variables, clippy::unnecessary_mut_passed)] @@ -127,6 +127,20 @@ fn main() { 0 } } + + let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + let _ = std::path::Path::new(".").join(&&"."); + deref_target_is_x(&X); + multiple_constraints(&[[""]]); + multiple_constraints_normalizes_to_same(&X, X); + let _ = Some("").unwrap_or(&""); + + only_sized(&""); // Don't lint. `Sized` is only bound + let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound + let _ = Box::new(&""); // Don't lint. Type parameter appears in return type + ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter + refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't + multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments } #[allow(clippy::needless_borrowed_reference)] @@ -183,3 +197,104 @@ mod issue9160 { } } } + +#[derive(Clone, Copy)] +struct X; + +impl std::ops::Deref for X { + type Target = X; + fn deref(&self) -> &Self::Target { + self + } +} + +fn deref_target_is_x<T>(_: T) +where + T: std::ops::Deref<Target = X>, +{ +} + +fn multiple_constraints<T, U, V, X, Y>(_: T) +where + T: IntoIterator<Item = U> + IntoIterator<Item = X>, + U: IntoIterator<Item = V>, + V: AsRef<str>, + X: IntoIterator<Item = Y>, + Y: AsRef<std::ffi::OsStr>, +{ +} + +fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V) +where + T: std::ops::Deref<Target = U>, + U: std::ops::Deref<Target = V>, +{ +} + +fn only_sized<T>(_: T) {} + +fn ref_as_ref_path<T: 'static>(_: &'static T) +where + &'static T: AsRef<std::path::Path>, +{ +} + +trait RefsOnly { + type Referent; +} + +impl<T> RefsOnly for &T { + type Referent = T; +} + +fn refs_only<T, U>(_: T) +where + T: RefsOnly<Referent = U>, +{ +} + +fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U) +where + T: IntoIterator<Item = U>, + U: IntoIterator<Item = V>, + V: AsRef<str>, +{ +} + +// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321 +#[allow(dead_code)] +mod copyable_iterator { + #[derive(Clone, Copy)] + struct Iter; + impl Iterator for Iter { + type Item = (); + fn next(&mut self) -> Option<Self::Item> { + None + } + } + fn takes_iter(_: impl Iterator) {} + fn dont_warn(mut x: Iter) { + takes_iter(&mut x); + } + fn warn(mut x: &mut Iter) { + takes_iter(&mut x) + } +} + +mod under_msrv { + #![allow(dead_code)] + #![clippy::msrv = "1.52.0"] + + fn foo() { + let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + } +} + +mod meets_msrv { + #![allow(dead_code)] + #![clippy::msrv = "1.53.0"] + + fn foo() { + let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + } +} diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr index 66588689d..5af68706d 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.stderr +++ b/src/tools/clippy/tests/ui/needless_borrow.stderr @@ -120,17 +120,59 @@ error: this expression creates a reference which is immediately dereferenced by LL | (&&5).foo(); | ^^^^^ help: change this to: `(&5)` +error: the borrowed expression implements the required traits + --> $DIR/needless_borrow.rs:131:51 + | +LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]` + +error: the borrowed expression implements the required traits + --> $DIR/needless_borrow.rs:132:44 + | +LL | let _ = std::path::Path::new(".").join(&&"."); + | ^^^^^ help: change this to: `"."` + +error: the borrowed expression implements the required traits + --> $DIR/needless_borrow.rs:133:23 + | +LL | deref_target_is_x(&X); + | ^^ help: change this to: `X` + +error: the borrowed expression implements the required traits + --> $DIR/needless_borrow.rs:134:26 + | +LL | multiple_constraints(&[[""]]); + | ^^^^^^^ help: change this to: `[[""]]` + +error: the borrowed expression implements the required traits + --> $DIR/needless_borrow.rs:135:45 + | +LL | multiple_constraints_normalizes_to_same(&X, X); + | ^^ help: change this to: `X` + +error: this expression creates a reference which is immediately dereferenced by the compiler + --> $DIR/needless_borrow.rs:136:32 + | +LL | let _ = Some("").unwrap_or(&""); + | ^^^ help: change this to: `""` + error: this expression borrows a value the compiler would automatically borrow - --> $DIR/needless_borrow.rs:173:13 + --> $DIR/needless_borrow.rs:187:13 | LL | (&self.f)() | ^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> $DIR/needless_borrow.rs:182:13 + --> $DIR/needless_borrow.rs:196:13 | LL | (&mut self.f)() | ^^^^^^^^^^^^^ help: change this to: `(self.f)` -error: aborting due to 22 previous errors +error: the borrowed expression implements the required traits + --> $DIR/needless_borrow.rs:298:55 + | +LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]` + +error: aborting due to 29 previous errors diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.rs b/src/tools/clippy/tests/ui/needless_collect_indirect.rs index 1f11d1f8d..12a9ace1e 100644 --- a/src/tools/clippy/tests/ui/needless_collect_indirect.rs +++ b/src/tools/clippy/tests/ui/needless_collect_indirect.rs @@ -112,3 +112,192 @@ fn allow_test() { let v = [1].iter().collect::<Vec<_>>(); v.into_iter().collect::<HashSet<_>>(); } + +mod issue_8553 { + fn test_for() { + let vec = vec![1, 2]; + let w: Vec<usize> = vec.iter().map(|i| i * i).collect(); + + for i in 0..2 { + // Do not lint, because this method call is in the loop + w.contains(&i); + } + + for i in 0..2 { + let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); + // Do lint + y.contains(&i); + for j in 0..2 { + // Do not lint, because this method call is in the loop + z.contains(&j); + } + } + + // Do not lint, because this variable is used. + w.contains(&0); + } + + fn test_while() { + let vec = vec![1, 2]; + let x: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let mut n = 0; + while n > 1 { + // Do not lint, because this method call is in the loop + x.contains(&n); + n += 1; + } + + while n > 2 { + let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); + // Do lint + y.contains(&n); + n += 1; + while n > 4 { + // Do not lint, because this method call is in the loop + z.contains(&n); + n += 1; + } + } + } + + fn test_loop() { + let vec = vec![1, 2]; + let x: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let mut n = 0; + loop { + if n < 1 { + // Do not lint, because this method call is in the loop + x.contains(&n); + n += 1; + } else { + break; + } + } + + loop { + if n < 2 { + let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); + // Do lint + y.contains(&n); + n += 1; + loop { + if n < 4 { + // Do not lint, because this method call is in the loop + z.contains(&n); + n += 1; + } else { + break; + } + } + } else { + break; + } + } + } + + fn test_while_let() { + let vec = vec![1, 2]; + let x: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let optional = Some(0); + let mut n = 0; + while let Some(value) = optional { + if n < 1 { + // Do not lint, because this method call is in the loop + x.contains(&n); + n += 1; + } else { + break; + } + } + + while let Some(value) = optional { + let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); + if n < 2 { + // Do lint + y.contains(&n); + n += 1; + } else { + break; + } + + while let Some(value) = optional { + if n < 4 { + // Do not lint, because this method call is in the loop + z.contains(&n); + n += 1; + } else { + break; + } + } + } + } + + fn test_if_cond() { + let vec = vec![1, 2]; + let v: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let w = v.iter().collect::<Vec<_>>(); + // Do lint + for _ in 0..w.len() { + todo!(); + } + } + + fn test_if_cond_false_case() { + let vec = vec![1, 2]; + let v: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let w = v.iter().collect::<Vec<_>>(); + // Do not lint, because w is used. + for _ in 0..w.len() { + todo!(); + } + + w.len(); + } + + fn test_while_cond() { + let mut vec = vec![1, 2]; + let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let mut w = v.iter().collect::<Vec<_>>(); + // Do lint + while 1 == w.len() { + todo!(); + } + } + + fn test_while_cond_false_case() { + let mut vec = vec![1, 2]; + let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let mut w = v.iter().collect::<Vec<_>>(); + // Do not lint, because w is used. + while 1 == w.len() { + todo!(); + } + + w.len(); + } + + fn test_while_let_cond() { + let mut vec = vec![1, 2]; + let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let mut w = v.iter().collect::<Vec<_>>(); + // Do lint + while let Some(i) = Some(w.len()) { + todo!(); + } + } + + fn test_while_let_cond_false_case() { + let mut vec = vec![1, 2]; + let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect(); + let mut w = v.iter().collect::<Vec<_>>(); + // Do not lint, because w is used. + while let Some(i) = Some(w.len()) { + todo!(); + } + w.len(); + } +} diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr index 0f5e78f91..9f0880cc6 100644 --- a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr +++ b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr @@ -125,5 +125,122 @@ LL ~ LL ~ sample.iter().count() | -error: aborting due to 9 previous errors +error: avoid using `collect()` when not needed + --> $DIR/needless_collect_indirect.rs:127:59 + | +LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + | ^^^^^^^ +... +LL | y.contains(&i); + | -------------- the iterator could be used here instead + | +help: check if the original Iterator contains an element instead of collecting then checking + | +LL ~ +LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); +LL | // Do lint +LL ~ vec.iter().map(|k| k * k).any(|x| x == i); + | + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect_indirect.rs:152:59 + | +LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + | ^^^^^^^ +... +LL | y.contains(&n); + | -------------- the iterator could be used here instead + | +help: check if the original Iterator contains an element instead of collecting then checking + | +LL ~ +LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); +LL | // Do lint +LL ~ vec.iter().map(|k| k * k).any(|x| x == n); + | + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect_indirect.rs:181:63 + | +LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + | ^^^^^^^ +... +LL | y.contains(&n); + | -------------- the iterator could be used here instead + | +help: check if the original Iterator contains an element instead of collecting then checking + | +LL ~ +LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); +LL | // Do lint +LL ~ vec.iter().map(|k| k * k).any(|x| x == n); + | + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect_indirect.rs:217:59 + | +LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect(); + | ^^^^^^^ +... +LL | y.contains(&n); + | -------------- the iterator could be used here instead + | +help: check if the original Iterator contains an element instead of collecting then checking + | +LL ~ +LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect(); +LL | if n < 2 { +LL | // Do lint +LL ~ vec.iter().map(|k| k * k).any(|x| x == n); + | + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect_indirect.rs:242:26 + | +LL | let w = v.iter().collect::<Vec<_>>(); + | ^^^^^^^ +LL | // Do lint +LL | for _ in 0..w.len() { + | ------- the iterator could be used here instead + | +help: take the original Iterator's count instead of collecting it and finding the length + | +LL ~ +LL | // Do lint +LL ~ for _ in 0..v.iter().count() { + | + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect_indirect.rs:264:30 + | +LL | let mut w = v.iter().collect::<Vec<_>>(); + | ^^^^^^^ +LL | // Do lint +LL | while 1 == w.len() { + | ------- the iterator could be used here instead + | +help: take the original Iterator's count instead of collecting it and finding the length + | +LL ~ +LL | // Do lint +LL ~ while 1 == v.iter().count() { + | + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect_indirect.rs:286:30 + | +LL | let mut w = v.iter().collect::<Vec<_>>(); + | ^^^^^^^ +LL | // Do lint +LL | while let Some(i) = Some(w.len()) { + | ------- the iterator could be used here instead + | +help: take the original Iterator's count instead of collecting it and finding the length + | +LL ~ +LL | // Do lint +LL ~ while let Some(i) = Some(v.iter().count()) { + | + +error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/needless_match.fixed b/src/tools/clippy/tests/ui/needless_match.fixed index 0c9178fb8..7e4740679 100644 --- a/src/tools/clippy/tests/ui/needless_match.fixed +++ b/src/tools/clippy/tests/ui/needless_match.fixed @@ -207,4 +207,43 @@ impl Tr for Result<i32, i32> { } } +mod issue9084 { + fn wildcard_if() { + let mut some_bool = true; + let e = Some(1); + + // should lint + let _ = e; + + // should lint + let _ = e; + + // should not lint + let _ = match e { + _ if some_bool => e, + _ => Some(2), + }; + + // should not lint + let _ = match e { + Some(i) => Some(i + 1), + _ if some_bool => e, + _ => e, + }; + + // should not lint (guard has side effects) + let _ = match e { + Some(i) => Some(i), + _ if { + some_bool = false; + some_bool + } => + { + e + }, + _ => e, + }; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_match.rs b/src/tools/clippy/tests/ui/needless_match.rs index f66f01d7c..809c694bf 100644 --- a/src/tools/clippy/tests/ui/needless_match.rs +++ b/src/tools/clippy/tests/ui/needless_match.rs @@ -244,4 +244,50 @@ impl Tr for Result<i32, i32> { } } +mod issue9084 { + fn wildcard_if() { + let mut some_bool = true; + let e = Some(1); + + // should lint + let _ = match e { + _ if some_bool => e, + _ => e, + }; + + // should lint + let _ = match e { + Some(i) => Some(i), + _ if some_bool => e, + _ => e, + }; + + // should not lint + let _ = match e { + _ if some_bool => e, + _ => Some(2), + }; + + // should not lint + let _ = match e { + Some(i) => Some(i + 1), + _ if some_bool => e, + _ => e, + }; + + // should not lint (guard has side effects) + let _ = match e { + Some(i) => Some(i), + _ if { + some_bool = false; + some_bool + } => + { + e + }, + _ => e, + }; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_match.stderr b/src/tools/clippy/tests/ui/needless_match.stderr index 5bc79800a..28e78441c 100644 --- a/src/tools/clippy/tests/ui/needless_match.stderr +++ b/src/tools/clippy/tests/ui/needless_match.stderr @@ -109,5 +109,26 @@ LL | | Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB( LL | | }; | |_________^ help: replace it with: `ce` -error: aborting due to 11 previous errors +error: this match expression is unnecessary + --> $DIR/needless_match.rs:253:17 + | +LL | let _ = match e { + | _________________^ +LL | | _ if some_bool => e, +LL | | _ => e, +LL | | }; + | |_________^ help: replace it with: `e` + +error: this match expression is unnecessary + --> $DIR/needless_match.rs:259:17 + | +LL | let _ = match e { + | _________________^ +LL | | Some(i) => Some(i), +LL | | _ if some_bool => e, +LL | | _ => e, +LL | | }; + | |_________^ help: replace it with: `e` + +error: aborting due to 13 previous errors diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed index 0bc0d0011..695883e8d 100644 --- a/src/tools/clippy/tests/ui/needless_return.fixed +++ b/src/tools/clippy/tests/ui/needless_return.fixed @@ -1,7 +1,6 @@ // run-rustfix #![feature(lint_reasons)] -#![feature(let_else)] #![allow(unused)] #![allow( clippy::if_same_then_else, @@ -228,13 +227,9 @@ fn needless_return_macro() -> String { format!("Hello {}", "world!") } -fn check_expect() -> bool { - if true { - // no error! - return true; - } - #[expect(clippy::needless_return)] - return true; +fn issue_9361() -> i32 { + #[allow(clippy::integer_arithmetic)] + return 1 + 2; } fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs index eb9f72e8e..63d9fe9ec 100644 --- a/src/tools/clippy/tests/ui/needless_return.rs +++ b/src/tools/clippy/tests/ui/needless_return.rs @@ -1,7 +1,6 @@ // run-rustfix #![feature(lint_reasons)] -#![feature(let_else)] #![allow(unused)] #![allow( clippy::if_same_then_else, @@ -228,13 +227,9 @@ fn needless_return_macro() -> String { return format!("Hello {}", "world!"); } -fn check_expect() -> bool { - if true { - // no error! - return true; - } - #[expect(clippy::needless_return)] - return true; +fn issue_9361() -> i32 { + #[allow(clippy::integer_arithmetic)] + return 1 + 2; } fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr index 83ff07638..cadee6e00 100644 --- a/src/tools/clippy/tests/ui/needless_return.stderr +++ b/src/tools/clippy/tests/ui/needless_return.stderr @@ -1,5 +1,5 @@ error: unneeded `return` statement - --> $DIR/needless_return.rs:27:5 + --> $DIR/needless_return.rs:26:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` @@ -7,217 +7,217 @@ LL | return true; = note: `-D clippy::needless-return` implied by `-D warnings` error: unneeded `return` statement - --> $DIR/needless_return.rs:31:5 + --> $DIR/needless_return.rs:30:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:36:9 + --> $DIR/needless_return.rs:35:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:38:9 + --> $DIR/needless_return.rs:37:9 | LL | return false; | ^^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:44:17 + --> $DIR/needless_return.rs:43:17 | LL | true => return false, | ^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:46:13 + --> $DIR/needless_return.rs:45:13 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:53:9 + --> $DIR/needless_return.rs:52:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:55:16 + --> $DIR/needless_return.rs:54:16 | LL | let _ = || return true; | ^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:59:5 + --> $DIR/needless_return.rs:58:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()` error: unneeded `return` statement - --> $DIR/needless_return.rs:63:5 + --> $DIR/needless_return.rs:62:5 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:68:9 + --> $DIR/needless_return.rs:67:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:70:9 + --> $DIR/needless_return.rs:69:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:77:14 + --> $DIR/needless_return.rs:76:14 | LL | _ => return, | ^^^^^^ help: replace `return` with a unit value: `()` error: unneeded `return` statement - --> $DIR/needless_return.rs:86:13 + --> $DIR/needless_return.rs:85:13 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:88:14 + --> $DIR/needless_return.rs:87:14 | LL | _ => return, | ^^^^^^ help: replace `return` with a unit value: `()` error: unneeded `return` statement - --> $DIR/needless_return.rs:101:9 + --> $DIR/needless_return.rs:100:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")` error: unneeded `return` statement - --> $DIR/needless_return.rs:103:9 + --> $DIR/needless_return.rs:102:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()` error: unneeded `return` statement - --> $DIR/needless_return.rs:125:32 + --> $DIR/needless_return.rs:124:32 | LL | bar.unwrap_or_else(|_| return) | ^^^^^^ help: replace `return` with an empty block: `{}` error: unneeded `return` statement - --> $DIR/needless_return.rs:130:13 + --> $DIR/needless_return.rs:129:13 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:132:20 + --> $DIR/needless_return.rs:131:20 | LL | let _ = || return; | ^^^^^^ help: replace `return` with an empty block: `{}` error: unneeded `return` statement - --> $DIR/needless_return.rs:138:32 + --> $DIR/needless_return.rs:137:32 | LL | res.unwrap_or_else(|_| return Foo) | ^^^^^^^^^^ help: remove `return`: `Foo` error: unneeded `return` statement - --> $DIR/needless_return.rs:147:5 + --> $DIR/needless_return.rs:146:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:151:5 + --> $DIR/needless_return.rs:150:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:156:9 + --> $DIR/needless_return.rs:155:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:158:9 + --> $DIR/needless_return.rs:157:9 | LL | return false; | ^^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:164:17 + --> $DIR/needless_return.rs:163:17 | LL | true => return false, | ^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:166:13 + --> $DIR/needless_return.rs:165:13 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:173:9 + --> $DIR/needless_return.rs:172:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:175:16 + --> $DIR/needless_return.rs:174:16 | LL | let _ = || return true; | ^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:179:5 + --> $DIR/needless_return.rs:178:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()` error: unneeded `return` statement - --> $DIR/needless_return.rs:183:5 + --> $DIR/needless_return.rs:182:5 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:188:9 + --> $DIR/needless_return.rs:187:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:190:9 + --> $DIR/needless_return.rs:189:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:197:14 + --> $DIR/needless_return.rs:196:14 | LL | _ => return, | ^^^^^^ help: replace `return` with a unit value: `()` error: unneeded `return` statement - --> $DIR/needless_return.rs:210:9 + --> $DIR/needless_return.rs:209:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")` error: unneeded `return` statement - --> $DIR/needless_return.rs:212:9 + --> $DIR/needless_return.rs:211:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()` error: unneeded `return` statement - --> $DIR/needless_return.rs:228:5 + --> $DIR/needless_return.rs:227:5 | LL | return format!("Hello {}", "world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `format!("Hello {}", "world!")` diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.rs b/src/tools/clippy/tests/ui/only_used_in_recursion.rs index 5768434f9..f71e8ead5 100644 --- a/src/tools/clippy/tests/ui/only_used_in_recursion.rs +++ b/src/tools/clippy/tests/ui/only_used_in_recursion.rs @@ -1,122 +1,113 @@ #![warn(clippy::only_used_in_recursion)] -fn simple(a: usize, b: usize) -> usize { - if a == 0 { 1 } else { simple(a - 1, b) } +fn _simple(x: u32) -> u32 { + x } -fn with_calc(a: usize, b: isize) -> usize { - if a == 0 { 1 } else { with_calc(a - 1, -b + 1) } +fn _simple2(x: u32) -> u32 { + _simple(x) } -fn tuple((a, b): (usize, usize)) -> usize { - if a == 0 { 1 } else { tuple((a - 1, b + 1)) } +fn _one_unused(flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { _one_unused(flag - 1, a) } } -fn let_tuple(a: usize, b: usize) -> usize { - let (c, d) = (a, b); - if c == 0 { 1 } else { let_tuple(c - 1, d + 1) } +fn _two_unused(flag: u32, a: u32, b: i32) -> usize { + if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } } -fn array([a, b]: [usize; 2]) -> usize { - if a == 0 { 1 } else { array([a - 1, b + 1]) } -} - -fn index(a: usize, mut b: &[usize], c: usize) -> usize { - if a == 0 { 1 } else { index(a - 1, b, c + b[0]) } -} - -fn break_(a: usize, mut b: usize, mut c: usize) -> usize { - let c = loop { - b += 1; - c += 1; - if c == 10 { - break b; - } - }; - - if a == 0 { 1 } else { break_(a - 1, c, c) } +fn _with_calc(flag: u32, a: i64) -> usize { + if flag == 0 { + 0 + } else { + _with_calc(flag - 1, (-a + 10) * 5) + } } -// this has a side effect -fn mut_ref(a: usize, b: &mut usize) -> usize { - *b = 1; - if a == 0 { 1 } else { mut_ref(a - 1, b) } +// Don't lint +fn _used_with_flag(flag: u32, a: u32) -> usize { + if flag == 0 { 0 } else { _used_with_flag(flag ^ a, a - 1) } } -fn mut_ref2(a: usize, b: &mut usize) -> usize { - let mut c = *b; - if a == 0 { 1 } else { mut_ref2(a - 1, &mut c) } +fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { + if flag == 0 { + 0 + } else { + _used_with_unused(flag - 1, -a, a + b) + } } -fn not_primitive(a: usize, b: String) -> usize { - if a == 0 { 1 } else { not_primitive(a - 1, b) } +fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { + if flag == 0 { + 0 + } else { + _codependent_unused(flag - 1, a * b, a + b) + } } -// this doesn't have a side effect, -// but `String` is not primitive. -fn not_primitive_op(a: usize, b: String, c: &str) -> usize { - if a == 1 { 1 } else { not_primitive_op(a, b + c, c) } +fn _not_primitive(flag: u32, b: String) -> usize { + if flag == 0 { 0 } else { _not_primitive(flag - 1, b) } } struct A; impl A { - fn method(a: usize, b: usize) -> usize { - if a == 0 { 1 } else { A::method(a - 1, b - 1) } + fn _method(flag: usize, a: usize) -> usize { + if flag == 0 { 0 } else { Self::_method(flag - 1, a) } } - fn method2(&self, a: usize, b: usize) -> usize { - if a == 0 { 1 } else { self.method2(a - 1, b + 1) } + fn _method_self(&self, flag: usize, a: usize) -> usize { + if flag == 0 { 0 } else { self._method_self(flag - 1, a) } } } trait B { - fn hello(a: usize, b: usize) -> usize; - - fn hello2(&self, a: usize, b: usize) -> usize; + fn method(flag: u32, a: usize) -> usize; + fn method_self(&self, flag: u32, a: usize) -> usize; } impl B for A { - fn hello(a: usize, b: usize) -> usize { - if a == 0 { 1 } else { A::hello(a - 1, b + 1) } + fn method(flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { Self::method(flag - 1, a) } } - fn hello2(&self, a: usize, b: usize) -> usize { - if a == 0 { 1 } else { self.hello2(a - 1, b + 1) } + fn method_self(&self, flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { self.method_self(flag - 1, a) } } } -trait C { - fn hello(a: usize, b: usize) -> usize { - if a == 0 { 1 } else { Self::hello(a - 1, b + 1) } +impl B for () { + fn method(flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { a } } - fn hello2(&self, a: usize, b: usize) -> usize { - if a == 0 { 1 } else { self.hello2(a - 1, b + 1) } + fn method_self(&self, flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { a } } } -fn ignore(a: usize, _: usize) -> usize { - if a == 1 { 1 } else { ignore(a - 1, 0) } -} +impl B for u32 { + fn method(flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { <() as B>::method(flag, a) } + } -fn ignore2(a: usize, _b: usize) -> usize { - if a == 1 { 1 } else { ignore2(a - 1, _b) } + fn method_self(&self, flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { ().method_self(flag, a) } + } } -fn f1(a: u32) -> u32 { - a -} +trait C { + fn method(flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { Self::method(flag - 1, a) } + } -fn f2(a: u32) -> u32 { - f1(a) + fn method_self(&self, flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { self.method_self(flag - 1, a) } + } } -fn inner_fn(a: u32) -> u32 { - fn inner_fn(a: u32) -> u32 { - a - } - inner_fn(a) +fn _ignore(flag: usize, _a: usize) -> usize { + if flag == 0 { 0 } else { _ignore(flag - 1, _a) } } fn main() {} diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr index 6fe9361bf..74057ddcf 100644 --- a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr +++ b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr @@ -1,82 +1,195 @@ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:3:21 + --> $DIR/only_used_in_recursion.rs:11:27 | -LL | fn simple(a: usize, b: usize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +LL | fn _one_unused(flag: u32, a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` | = note: `-D clippy::only-used-in-recursion` implied by `-D warnings` +note: parameter used here + --> $DIR/only_used_in_recursion.rs:12:53 + | +LL | if flag == 0 { 0 } else { _one_unused(flag - 1, a) } + | ^ + +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion.rs:15:27 + | +LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:16:53 + | +LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } + | ^ + +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion.rs:15:35 + | +LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:16:56 + | +LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } + | ^ + +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion.rs:19:26 + | +LL | fn _with_calc(flag: u32, a: i64) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:23:32 + | +LL | _with_calc(flag - 1, (-a + 10) * 5) + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:7:24 + --> $DIR/only_used_in_recursion.rs:32:33 + | +LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:36:38 | -LL | fn with_calc(a: usize, b: isize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +LL | _used_with_unused(flag - 1, -a, a + b) + | ^ ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:11:14 + --> $DIR/only_used_in_recursion.rs:32:41 + | +LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:36:45 | -LL | fn tuple((a, b): (usize, usize)) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +LL | _used_with_unused(flag - 1, -a, a + b) + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:15:24 + --> $DIR/only_used_in_recursion.rs:40:35 | -LL | fn let_tuple(a: usize, b: usize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:44:39 + | +LL | _codependent_unused(flag - 1, a * b, a + b) + | ^ ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:20:14 + --> $DIR/only_used_in_recursion.rs:40:43 + | +LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` | -LL | fn array([a, b]: [usize; 2]) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +note: parameter used here + --> $DIR/only_used_in_recursion.rs:44:43 + | +LL | _codependent_unused(flag - 1, a * b, a + b) + | ^ ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:24:20 + --> $DIR/only_used_in_recursion.rs:48:30 + | +LL | fn _not_primitive(flag: u32, b: String) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` | -LL | fn index(a: usize, mut b: &[usize], c: usize) -> usize { - | ^^^^^ help: if this is intentional, prefix with an underscore: `_b` +note: parameter used here + --> $DIR/only_used_in_recursion.rs:49:56 + | +LL | if flag == 0 { 0 } else { _not_primitive(flag - 1, b) } + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:24:37 + --> $DIR/only_used_in_recursion.rs:55:29 + | +LL | fn _method(flag: usize, a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:56:59 | -LL | fn index(a: usize, mut b: &[usize], c: usize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_c` +LL | if flag == 0 { 0 } else { Self::_method(flag - 1, a) } + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:28:21 + --> $DIR/only_used_in_recursion.rs:59:22 + | +LL | fn _method_self(&self, flag: usize, a: usize) -> usize { + | ^^^^ + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:60:35 | -LL | fn break_(a: usize, mut b: usize, mut c: usize) -> usize { - | ^^^^^ help: if this is intentional, prefix with an underscore: `_b` +LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) } + | ^^^^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:46:23 + --> $DIR/only_used_in_recursion.rs:59:41 | -LL | fn mut_ref2(a: usize, b: &mut usize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +LL | fn _method_self(&self, flag: usize, a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:60:63 + | +LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) } + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:51:28 + --> $DIR/only_used_in_recursion.rs:70:26 + | +LL | fn method(flag: u32, a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` | -LL | fn not_primitive(a: usize, b: String) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +note: parameter used here + --> $DIR/only_used_in_recursion.rs:71:58 + | +LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) } + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:68:33 + --> $DIR/only_used_in_recursion.rs:74:38 + | +LL | fn method_self(&self, flag: u32, a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` | -LL | fn method2(&self, a: usize, b: usize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +note: parameter used here + --> $DIR/only_used_in_recursion.rs:75:62 + | +LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) } + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:90:24 + --> $DIR/only_used_in_recursion.rs:100:26 + | +LL | fn method(flag: u32, a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:101:58 | -LL | fn hello(a: usize, b: usize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) } + | ^ error: parameter is only used in recursion - --> $DIR/only_used_in_recursion.rs:94:32 + --> $DIR/only_used_in_recursion.rs:104:38 + | +LL | fn method_self(&self, flag: u32, a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion.rs:105:62 | -LL | fn hello2(&self, a: usize, b: usize) -> usize { - | ^ help: if this is intentional, prefix with an underscore: `_b` +LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) } + | ^ -error: aborting due to 13 previous errors +error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.rs b/src/tools/clippy/tests/ui/only_used_in_recursion2.rs new file mode 100644 index 000000000..45dd0553f --- /dev/null +++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.rs @@ -0,0 +1,91 @@ +#![warn(clippy::only_used_in_recursion)] + +fn _with_inner(flag: u32, a: u32, b: u32) -> usize { + fn inner(flag: u32, a: u32) -> u32 { + if flag == 0 { 0 } else { inner(flag, a) } + } + + let x = inner(flag, a); + if flag == 0 { 0 } else { _with_inner(flag, a, b + x) } +} + +fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 { + if let Some(x) = a.and_then(|x| f(x, x)) { + _with_closure(Some(x), b, f) + } else { + 0 + } +} + +// Issue #8560 +trait D { + fn foo(&mut self, arg: u32) -> u32; +} + +mod m { + pub struct S(u32); + impl S { + pub fn foo(&mut self, arg: u32) -> u32 { + arg + self.0 + } + } +} + +impl D for m::S { + fn foo(&mut self, arg: u32) -> u32 { + self.foo(arg) + } +} + +// Issue #8782 +fn only_let(x: u32) { + let y = 10u32; + let _z = x * y; +} + +trait E<T: E<()>> { + fn method(flag: u32, a: usize) -> usize { + if flag == 0 { + 0 + } else { + <T as E<()>>::method(flag - 1, a) + } + } +} + +impl E<()> for () { + fn method(flag: u32, a: usize) -> usize { + if flag == 0 { 0 } else { a } + } +} + +fn overwritten_param(flag: u32, mut a: usize) -> usize { + if flag == 0 { + return 0; + } else if flag > 5 { + a += flag as usize; + } else { + a = 5; + } + overwritten_param(flag, a) +} + +fn field_direct(flag: u32, mut a: (usize,)) -> usize { + if flag == 0 { + 0 + } else { + a.0 += 5; + field_direct(flag - 1, a) + } +} + +fn field_deref(flag: u32, a: &mut Box<(usize,)>) -> usize { + if flag == 0 { + 0 + } else { + a.0 += 5; + field_deref(flag - 1, a) + } +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr new file mode 100644 index 000000000..23f6ffd30 --- /dev/null +++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr @@ -0,0 +1,63 @@ +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion2.rs:3:35 + | +LL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + | + = note: `-D clippy::only-used-in-recursion` implied by `-D warnings` +note: parameter used here + --> $DIR/only_used_in_recursion2.rs:9:52 + | +LL | if flag == 0 { 0 } else { _with_inner(flag, a, b + x) } + | ^ + +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion2.rs:4:25 + | +LL | fn inner(flag: u32, a: u32) -> u32 { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion2.rs:5:47 + | +LL | if flag == 0 { 0 } else { inner(flag, a) } + | ^ + +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion2.rs:12:34 + | +LL | fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + | +note: parameter used here + --> $DIR/only_used_in_recursion2.rs:14:32 + | +LL | _with_closure(Some(x), b, f) + | ^ + +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion2.rs:62:37 + | +LL | fn overwritten_param(flag: u32, mut a: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion2.rs:70:29 + | +LL | overwritten_param(flag, a) + | ^ + +error: parameter is only used in recursion + --> $DIR/only_used_in_recursion2.rs:73:32 + | +LL | fn field_direct(flag: u32, mut a: (usize,)) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: parameter used here + --> $DIR/only_used_in_recursion2.rs:78:32 + | +LL | field_direct(flag - 1, a) + | ^ + +error: aborting due to 5 previous errors + diff --git a/src/tools/clippy/tests/ui/op_ref.rs b/src/tools/clippy/tests/ui/op_ref.rs index d8bf66603..07226b0a1 100644 --- a/src/tools/clippy/tests/ui/op_ref.rs +++ b/src/tools/clippy/tests/ui/op_ref.rs @@ -1,4 +1,4 @@ -#![allow(unused_variables, clippy::blacklisted_name)] +#![allow(unused_variables, clippy::disallowed_names)] #![warn(clippy::op_ref)] use std::collections::HashSet; use std::ops::{BitAnd, Mul}; diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed index b6d5e106f..f15ac551b 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.fixed +++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed @@ -179,4 +179,13 @@ fn main() { let _ = pattern_to_vec("hello world"); let _ = complex_subpat(); + + // issue #8492 + let _ = s.map_or(1, |string| string.len()); + let _ = Some(10).map_or(5, |a| a + 1); + + let res: Result<i32, i32> = Ok(5); + let _ = res.map_or(1, |a| a + 1); + let _ = res.map_or(1, |a| a + 1); + let _ = res.map_or(5, |a| a + 1); } diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs index 35bae1593..9eeaea12d 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.rs +++ b/src/tools/clippy/tests/ui/option_if_let_else.rs @@ -208,4 +208,25 @@ fn main() { let _ = pattern_to_vec("hello world"); let _ = complex_subpat(); + + // issue #8492 + let _ = match s { + Some(string) => string.len(), + None => 1, + }; + let _ = match Some(10) { + Some(a) => a + 1, + None => 5, + }; + + let res: Result<i32, i32> = Ok(5); + let _ = match res { + Ok(a) => a + 1, + _ => 1, + }; + let _ = match res { + Err(_) => 1, + Ok(a) => a + 1, + }; + let _ = if let Ok(a) = res { a + 1 } else { 5 }; } diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr index daba60600..a5dbf6e1f 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.stderr +++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr @@ -206,5 +206,51 @@ LL + s.len() + x LL ~ }); | -error: aborting due to 15 previous errors +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:213:13 + | +LL | let _ = match s { + | _____________^ +LL | | Some(string) => string.len(), +LL | | None => 1, +LL | | }; + | |_____^ help: try: `s.map_or(1, |string| string.len())` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:217:13 + | +LL | let _ = match Some(10) { + | _____________^ +LL | | Some(a) => a + 1, +LL | | None => 5, +LL | | }; + | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:223:13 + | +LL | let _ = match res { + | _____________^ +LL | | Ok(a) => a + 1, +LL | | _ => 1, +LL | | }; + | |_____^ help: try: `res.map_or(1, |a| a + 1)` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:227:13 + | +LL | let _ = match res { + | _____________^ +LL | | Err(_) => 1, +LL | | Ok(a) => a + 1, +LL | | }; + | |_____^ help: try: `res.map_or(1, |a| a + 1)` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:231:13 + | +LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` + +error: aborting due to 20 previous errors diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed index fdb08d953..5991188ab 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.fixed +++ b/src/tools/clippy/tests/ui/or_fun_call.fixed @@ -79,19 +79,19 @@ fn or_fun_call() { without_default.unwrap_or_else(Foo::new); let mut map = HashMap::<u64, String>::new(); - map.entry(42).or_insert(String::new()); + map.entry(42).or_default(); let mut map_vec = HashMap::<u64, Vec<i32>>::new(); - map_vec.entry(42).or_insert(vec![]); + map_vec.entry(42).or_default(); let mut btree = BTreeMap::<u64, String>::new(); - btree.entry(42).or_insert(String::new()); + btree.entry(42).or_default(); let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new(); - btree_vec.entry(42).or_insert(vec![]); + btree_vec.entry(42).or_default(); - let stringy = Some(String::from("")); - let _ = stringy.unwrap_or_else(|| "".to_owned()); + let stringy = Some(String::new()); + let _ = stringy.unwrap_or_default(); let opt = Some(1); let hello = "Hello"; diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs index 57ab5f03e..c353b41e4 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.rs +++ b/src/tools/clippy/tests/ui/or_fun_call.rs @@ -90,8 +90,8 @@ fn or_fun_call() { let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new(); btree_vec.entry(42).or_insert(vec![]); - let stringy = Some(String::from("")); - let _ = stringy.unwrap_or("".to_owned()); + let stringy = Some(String::new()); + let _ = stringy.unwrap_or(String::new()); let opt = Some(1); let hello = "Hello"; diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr index 4c5938ab8..e3dab4cb1 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.stderr +++ b/src/tools/clippy/tests/ui/or_fun_call.stderr @@ -66,11 +66,35 @@ error: use of `unwrap_or` followed by a function call LL | without_default.unwrap_or(Foo::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)` -error: use of `unwrap_or` followed by a function call +error: use of `or_insert` followed by a call to `new` + --> $DIR/or_fun_call.rs:82:19 + | +LL | map.entry(42).or_insert(String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + +error: use of `or_insert` followed by a call to `new` + --> $DIR/or_fun_call.rs:85:23 + | +LL | map_vec.entry(42).or_insert(vec![]); + | ^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + +error: use of `or_insert` followed by a call to `new` + --> $DIR/or_fun_call.rs:88:21 + | +LL | btree.entry(42).or_insert(String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + +error: use of `or_insert` followed by a call to `new` + --> $DIR/or_fun_call.rs:91:25 + | +LL | btree_vec.entry(42).or_insert(vec![]); + | ^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + +error: use of `unwrap_or` followed by a call to `new` --> $DIR/or_fun_call.rs:94:21 | -LL | let _ = stringy.unwrap_or("".to_owned()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())` +LL | let _ = stringy.unwrap_or(String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` error: use of `unwrap_or` followed by a function call --> $DIR/or_fun_call.rs:102:21 @@ -132,5 +156,5 @@ error: use of `unwrap_or` followed by a call to `new` LL | .unwrap_or(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` -error: aborting due to 22 previous errors +error: aborting due to 26 previous errors diff --git a/src/tools/clippy/tests/ui/logic_bug.rs b/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs index dd6b1db5f..04a30a832 100644 --- a/src/tools/clippy/tests/ui/logic_bug.rs +++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs @@ -1,6 +1,6 @@ #![feature(lint_reasons)] #![allow(unused, clippy::diverging_sub_expression)] -#![warn(clippy::logic_bug)] +#![warn(clippy::overly_complex_bool_expr)] fn main() { let a: bool = unimplemented!(); @@ -29,6 +29,6 @@ fn equality_stuff() { fn check_expect() { let a: i32 = unimplemented!(); let b: i32 = unimplemented!(); - #[expect(clippy::logic_bug)] + #[expect(clippy::overly_complex_bool_expr)] let _ = a < b && a >= b; } diff --git a/src/tools/clippy/tests/ui/logic_bug.stderr b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr index 4021fbf45..158cae8b8 100644 --- a/src/tools/clippy/tests/ui/logic_bug.stderr +++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr @@ -1,60 +1,60 @@ error: this boolean expression contains a logic bug - --> $DIR/logic_bug.rs:11:13 + --> $DIR/overly_complex_bool_expr.rs:11:13 | LL | let _ = a && b || a; | ^^^^^^^^^^^ help: it would look like the following: `a` | - = note: `-D clippy::logic-bug` implied by `-D warnings` + = note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings` help: this expression can be optimized out by applying boolean operations to the outer expression - --> $DIR/logic_bug.rs:11:18 + --> $DIR/overly_complex_bool_expr.rs:11:18 | LL | let _ = a && b || a; | ^ error: this boolean expression contains a logic bug - --> $DIR/logic_bug.rs:13:13 + --> $DIR/overly_complex_bool_expr.rs:13:13 | LL | let _ = false && a; | ^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> $DIR/logic_bug.rs:13:22 + --> $DIR/overly_complex_bool_expr.rs:13:22 | LL | let _ = false && a; | ^ error: this boolean expression contains a logic bug - --> $DIR/logic_bug.rs:23:13 + --> $DIR/overly_complex_bool_expr.rs:23:13 | LL | let _ = a == b && a != b; | ^^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> $DIR/logic_bug.rs:23:13 + --> $DIR/overly_complex_bool_expr.rs:23:13 | LL | let _ = a == b && a != b; | ^^^^^^ error: this boolean expression contains a logic bug - --> $DIR/logic_bug.rs:24:13 + --> $DIR/overly_complex_bool_expr.rs:24:13 | LL | let _ = a < b && a >= b; | ^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> $DIR/logic_bug.rs:24:13 + --> $DIR/overly_complex_bool_expr.rs:24:13 | LL | let _ = a < b && a >= b; | ^^^^^ error: this boolean expression contains a logic bug - --> $DIR/logic_bug.rs:25:13 + --> $DIR/overly_complex_bool_expr.rs:25:13 | LL | let _ = a > b && a <= b; | ^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> $DIR/logic_bug.rs:25:13 + --> $DIR/overly_complex_bool_expr.rs:25:13 | LL | let _ = a > b && a <= b; | ^^^^^ diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.fixed b/src/tools/clippy/tests/ui/partialeq_to_none.fixed new file mode 100644 index 000000000..4644ea8f5 --- /dev/null +++ b/src/tools/clippy/tests/ui/partialeq_to_none.fixed @@ -0,0 +1,74 @@ +// run-rustfix +#![warn(clippy::partialeq_to_none)] + +struct Foobar; + +impl PartialEq<Option<()>> for Foobar { + fn eq(&self, _: &Option<()>) -> bool { + false + } +} + +#[allow(dead_code)] +fn foo(f: Option<u32>) -> &'static str { + if f.is_some() { "yay" } else { "nay" } +} + +fn foobar() -> Option<()> { + None +} + +fn bar() -> Result<(), ()> { + Ok(()) +} + +fn optref() -> &'static &'static Option<()> { + &&None +} + +pub fn macro_expansion() { + macro_rules! foo { + () => { + None::<()> + }; + } + + let _ = foobar() == foo!(); + let _ = foo!() == foobar(); + let _ = foo!() == foo!(); +} + +fn main() { + let x = Some(0); + + let _ = x.is_none(); + let _ = x.is_some(); + let _ = x.is_none(); + let _ = x.is_some(); + + if foobar().is_none() {} + + if bar().ok().is_some() {} + + let _ = Some(1 + 2).is_some(); + + let _ = { Some(0) }.is_none(); + + let _ = { + /* + This comment runs long + */ + Some(1) + }.is_some(); + + // Should not trigger, as `Foobar` is not an `Option` and has no `is_none` + let _ = Foobar == None; + + let _ = optref().is_none(); + let _ = optref().is_some(); + let _ = optref().is_none(); + let _ = optref().is_some(); + + let x = Box::new(Option::<()>::None); + let _ = (*x).is_some(); +} diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.rs b/src/tools/clippy/tests/ui/partialeq_to_none.rs new file mode 100644 index 000000000..61011b3a8 --- /dev/null +++ b/src/tools/clippy/tests/ui/partialeq_to_none.rs @@ -0,0 +1,74 @@ +// run-rustfix +#![warn(clippy::partialeq_to_none)] + +struct Foobar; + +impl PartialEq<Option<()>> for Foobar { + fn eq(&self, _: &Option<()>) -> bool { + false + } +} + +#[allow(dead_code)] +fn foo(f: Option<u32>) -> &'static str { + if f != None { "yay" } else { "nay" } +} + +fn foobar() -> Option<()> { + None +} + +fn bar() -> Result<(), ()> { + Ok(()) +} + +fn optref() -> &'static &'static Option<()> { + &&None +} + +pub fn macro_expansion() { + macro_rules! foo { + () => { + None::<()> + }; + } + + let _ = foobar() == foo!(); + let _ = foo!() == foobar(); + let _ = foo!() == foo!(); +} + +fn main() { + let x = Some(0); + + let _ = x == None; + let _ = x != None; + let _ = None == x; + let _ = None != x; + + if foobar() == None {} + + if bar().ok() != None {} + + let _ = Some(1 + 2) != None; + + let _ = { Some(0) } == None; + + let _ = { + /* + This comment runs long + */ + Some(1) + } != None; + + // Should not trigger, as `Foobar` is not an `Option` and has no `is_none` + let _ = Foobar == None; + + let _ = optref() == &&None; + let _ = &&None != optref(); + let _ = **optref() == None; + let _ = &None != *optref(); + + let x = Box::new(Option::<()>::None); + let _ = None != *x; +} diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.stderr b/src/tools/clippy/tests/ui/partialeq_to_none.stderr new file mode 100644 index 000000000..d06ab7aee --- /dev/null +++ b/src/tools/clippy/tests/ui/partialeq_to_none.stderr @@ -0,0 +1,110 @@ +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:14:8 + | +LL | if f != None { "yay" } else { "nay" } + | ^^^^^^^^^ help: use `Option::is_some()` instead: `f.is_some()` + | + = note: `-D clippy::partialeq-to-none` implied by `-D warnings` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:44:13 + | +LL | let _ = x == None; + | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:45:13 + | +LL | let _ = x != None; + | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:46:13 + | +LL | let _ = None == x; + | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:47:13 + | +LL | let _ = None != x; + | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:49:8 + | +LL | if foobar() == None {} + | ^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `foobar().is_none()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:51:8 + | +LL | if bar().ok() != None {} + | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `bar().ok().is_some()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:53:13 + | +LL | let _ = Some(1 + 2) != None; + | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `Some(1 + 2).is_some()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:55:13 + | +LL | let _ = { Some(0) } == None; + | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `{ Some(0) }.is_none()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:57:13 + | +LL | let _ = { + | _____________^ +LL | | /* +LL | | This comment runs long +LL | | */ +LL | | Some(1) +LL | | } != None; + | |_____________^ + | +help: use `Option::is_some()` instead + | +LL ~ let _ = { +LL + /* +LL + This comment runs long +LL + */ +LL + Some(1) +LL ~ }.is_some(); + | + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:67:13 + | +LL | let _ = optref() == &&None; + | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:68:13 + | +LL | let _ = &&None != optref(); + | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:69:13 + | +LL | let _ = **optref() == None; + | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:70:13 + | +LL | let _ = &None != *optref(); + | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()` + +error: binary comparison to literal `Option::None` + --> $DIR/partialeq_to_none.rs:73:13 + | +LL | let _ = None != *x; + | ^^^^^^^^^^ help: use `Option::is_some()` instead: `(*x).is_some()` + +error: aborting due to 15 previous errors + diff --git a/src/tools/clippy/tests/ui/positional_named_format_parameters.fixed b/src/tools/clippy/tests/ui/positional_named_format_parameters.fixed new file mode 100644 index 000000000..4170e1098 --- /dev/null +++ b/src/tools/clippy/tests/ui/positional_named_format_parameters.fixed @@ -0,0 +1,56 @@ +// run-rustfix +#![allow(unused_must_use)] +#![allow(named_arguments_used_positionally)] // Unstable at time of writing. +#![warn(clippy::positional_named_format_parameters)] + +use std::io::Write; + +fn main() { + let mut v = Vec::new(); + let hello = "Hello"; + + println!("{hello:.foo$}", foo = 2); + writeln!(v, "{hello:.foo$}", foo = 2); + + // Warnings + println!("{zero} {one:?}", zero = 0, one = 1); + println!("This is a test {zero} {one:?}", zero = 0, one = 1); + println!("Hello {one} is {two:.zero$}", zero = 5, one = hello, two = 0.01); + println!("Hello {one:zero$}!", zero = 5, one = 1); + println!("Hello {zero:one$}!", zero = 4, one = 1); + println!("Hello {zero:0one$}!", zero = 4, one = 1); + println!("Hello is {one:.zero$}", zero = 5, one = 0.01); + println!("Hello is {one:<6.zero$}", zero = 5, one = 0.01); + println!("{zero}, `{two:>8.one$}` has 3", zero = hello, one = 3, two = hello); + println!("Hello {one} is {two:.zero$}", zero = 5, one = hello, two = 0.01); + println!("Hello {world} {world}!", world = 5); + + writeln!(v, "{zero} {one:?}", zero = 0, one = 1); + writeln!(v, "This is a test {zero} {one:?}", zero = 0, one = 1); + writeln!(v, "Hello {one} is {two:.zero$}", zero = 5, one = hello, two = 0.01); + writeln!(v, "Hello {one:zero$}!", zero = 4, one = 1); + writeln!(v, "Hello {zero:one$}!", zero = 4, one = 1); + writeln!(v, "Hello {zero:0one$}!", zero = 4, one = 1); + writeln!(v, "Hello is {one:.zero$}", zero = 3, one = 0.01); + writeln!(v, "Hello is {one:<6.zero$}", zero = 2, one = 0.01); + writeln!(v, "{zero}, `{two:>8.one$}` has 3", zero = hello, one = 3, two = hello); + writeln!(v, "Hello {one} is {two:.zero$}", zero = 1, one = hello, two = 0.01); + writeln!(v, "Hello {world} {world}!", world = 0); + + // Tests from other files + println!("{w:w$}", w = 1); + println!("{p:.p$}", p = 1); + println!("{v}", v = 1); + println!("{v:v$}", v = 1); + println!("{v:v$}", v = 1); + println!("{v:v$.v$}", v = 1); + println!("{v:v$.v$}", v = 1); + println!("{v:v$.v$}", v = 1); + println!("{v:v$.v$}", v = 1); + println!("{v:v$.v$}", v = 1); + println!("{v:v$.v$}", v = 1); + println!("{v:v$.v$}", v = 1); + println!("{w:w$}", w = 1); + println!("{p:.p$}", p = 1); + println!("{:p$.w$}", 1, w = 1, p = 1); +} diff --git a/src/tools/clippy/tests/ui/positional_named_format_parameters.rs b/src/tools/clippy/tests/ui/positional_named_format_parameters.rs new file mode 100644 index 000000000..553d8494e --- /dev/null +++ b/src/tools/clippy/tests/ui/positional_named_format_parameters.rs @@ -0,0 +1,56 @@ +// run-rustfix +#![allow(unused_must_use)] +#![allow(named_arguments_used_positionally)] // Unstable at time of writing. +#![warn(clippy::positional_named_format_parameters)] + +use std::io::Write; + +fn main() { + let mut v = Vec::new(); + let hello = "Hello"; + + println!("{hello:.foo$}", foo = 2); + writeln!(v, "{hello:.foo$}", foo = 2); + + // Warnings + println!("{} {1:?}", zero = 0, one = 1); + println!("This is a test { } {000001:?}", zero = 0, one = 1); + println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + println!("Hello {1:0$}!", zero = 5, one = 1); + println!("Hello {0:1$}!", zero = 4, one = 1); + println!("Hello {0:01$}!", zero = 4, one = 1); + println!("Hello is {1:.*}", zero = 5, one = 0.01); + println!("Hello is {:<6.*}", zero = 5, one = 0.01); + println!("{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello); + println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + println!("Hello {world} {}!", world = 5); + + writeln!(v, "{} {1:?}", zero = 0, one = 1); + writeln!(v, "This is a test { } {000001:?}", zero = 0, one = 1); + writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + writeln!(v, "Hello {1:0$}!", zero = 4, one = 1); + writeln!(v, "Hello {0:1$}!", zero = 4, one = 1); + writeln!(v, "Hello {0:01$}!", zero = 4, one = 1); + writeln!(v, "Hello is {1:.*}", zero = 3, one = 0.01); + writeln!(v, "Hello is {:<6.*}", zero = 2, one = 0.01); + writeln!(v, "{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello); + writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01); + writeln!(v, "Hello {world} {}!", world = 0); + + // Tests from other files + println!("{:w$}", w = 1); + println!("{:.p$}", p = 1); + println!("{}", v = 1); + println!("{:0$}", v = 1); + println!("{0:0$}", v = 1); + println!("{:0$.0$}", v = 1); + println!("{0:0$.0$}", v = 1); + println!("{0:0$.v$}", v = 1); + println!("{0:v$.0$}", v = 1); + println!("{v:0$.0$}", v = 1); + println!("{v:v$.0$}", v = 1); + println!("{v:0$.v$}", v = 1); + println!("{:w$}", w = 1); + println!("{:.p$}", p = 1); + println!("{:p$.w$}", 1, w = 1, p = 1); +} diff --git a/src/tools/clippy/tests/ui/positional_named_format_parameters.stderr b/src/tools/clippy/tests/ui/positional_named_format_parameters.stderr new file mode 100644 index 000000000..48ddb6d67 --- /dev/null +++ b/src/tools/clippy/tests/ui/positional_named_format_parameters.stderr @@ -0,0 +1,418 @@ +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:16:16 + | +LL | println!("{} {1:?}", zero = 0, one = 1); + | ^ help: replace it with: `zero` + | + = note: `-D clippy::positional-named-format-parameters` implied by `-D warnings` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:16:19 + | +LL | println!("{} {1:?}", zero = 0, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:17:31 + | +LL | println!("This is a test { } {000001:?}", zero = 0, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:17:35 + | +LL | println!("This is a test { } {000001:?}", zero = 0, one = 1); + | ^^^^^^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:18:32 + | +LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:18:22 + | +LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `one` + +error: named parameter two is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:18:29 + | +LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `two` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:19:24 + | +LL | println!("Hello {1:0$}!", zero = 5, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:19:22 + | +LL | println!("Hello {1:0$}!", zero = 5, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:20:22 + | +LL | println!("Hello {0:1$}!", zero = 4, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:20:24 + | +LL | println!("Hello {0:1$}!", zero = 4, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:21:22 + | +LL | println!("Hello {0:01$}!", zero = 4, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:21:25 + | +LL | println!("Hello {0:01$}!", zero = 4, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:22:28 + | +LL | println!("Hello is {1:.*}", zero = 5, one = 0.01); + | ^ help: replace it with: `zero$` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:22:25 + | +LL | println!("Hello is {1:.*}", zero = 5, one = 0.01); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:23:29 + | +LL | println!("Hello is {:<6.*}", zero = 5, one = 0.01); + | ^ help: replace it with: `zero$` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:23:25 + | +LL | println!("Hello is {:<6.*}", zero = 5, one = 0.01); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:24:16 + | +LL | println!("{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:24:28 + | +LL | println!("{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello); + | ^ help: replace it with: `one$` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:25:32 + | +LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:25:22 + | +LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `one` + +error: named parameter two is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:25:29 + | +LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `two` + +error: named parameter world is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:26:30 + | +LL | println!("Hello {world} {}!", world = 5); + | ^ help: replace it with: `world` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:28:19 + | +LL | writeln!(v, "{} {1:?}", zero = 0, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:28:22 + | +LL | writeln!(v, "{} {1:?}", zero = 0, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:29:34 + | +LL | writeln!(v, "This is a test { } {000001:?}", zero = 0, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:29:38 + | +LL | writeln!(v, "This is a test { } {000001:?}", zero = 0, one = 1); + | ^^^^^^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:30:35 + | +LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:30:25 + | +LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `one` + +error: named parameter two is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:30:32 + | +LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01); + | ^ help: replace it with: `two` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:31:27 + | +LL | writeln!(v, "Hello {1:0$}!", zero = 4, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:31:25 + | +LL | writeln!(v, "Hello {1:0$}!", zero = 4, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:32:25 + | +LL | writeln!(v, "Hello {0:1$}!", zero = 4, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:32:27 + | +LL | writeln!(v, "Hello {0:1$}!", zero = 4, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:33:25 + | +LL | writeln!(v, "Hello {0:01$}!", zero = 4, one = 1); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:33:28 + | +LL | writeln!(v, "Hello {0:01$}!", zero = 4, one = 1); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:34:31 + | +LL | writeln!(v, "Hello is {1:.*}", zero = 3, one = 0.01); + | ^ help: replace it with: `zero$` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:34:28 + | +LL | writeln!(v, "Hello is {1:.*}", zero = 3, one = 0.01); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:35:32 + | +LL | writeln!(v, "Hello is {:<6.*}", zero = 2, one = 0.01); + | ^ help: replace it with: `zero$` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:35:28 + | +LL | writeln!(v, "Hello is {:<6.*}", zero = 2, one = 0.01); + | ^ help: replace it with: `one` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:36:19 + | +LL | writeln!(v, "{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:36:31 + | +LL | writeln!(v, "{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello); + | ^ help: replace it with: `one$` + +error: named parameter zero is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:37:35 + | +LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01); + | ^ help: replace it with: `zero` + +error: named parameter one is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:37:25 + | +LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01); + | ^ help: replace it with: `one` + +error: named parameter two is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:37:32 + | +LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01); + | ^ help: replace it with: `two` + +error: named parameter world is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:38:33 + | +LL | writeln!(v, "Hello {world} {}!", world = 0); + | ^ help: replace it with: `world` + +error: named parameter w is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:41:16 + | +LL | println!("{:w$}", w = 1); + | ^ help: replace it with: `w` + +error: named parameter p is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:42:16 + | +LL | println!("{:.p$}", p = 1); + | ^ help: replace it with: `p` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:43:16 + | +LL | println!("{}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:44:16 + | +LL | println!("{:0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:44:17 + | +LL | println!("{:0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:45:16 + | +LL | println!("{0:0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:45:18 + | +LL | println!("{0:0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:46:16 + | +LL | println!("{:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:46:20 + | +LL | println!("{:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:46:17 + | +LL | println!("{:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:47:16 + | +LL | println!("{0:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:47:21 + | +LL | println!("{0:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:47:18 + | +LL | println!("{0:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:48:16 + | +LL | println!("{0:0$.v$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:48:18 + | +LL | println!("{0:0$.v$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:49:16 + | +LL | println!("{0:v$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:49:21 + | +LL | println!("{0:v$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:50:21 + | +LL | println!("{v:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:50:18 + | +LL | println!("{v:0$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:51:21 + | +LL | println!("{v:v$.0$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter v is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:52:18 + | +LL | println!("{v:0$.v$}", v = 1); + | ^ help: replace it with: `v` + +error: named parameter w is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:53:16 + | +LL | println!("{:w$}", w = 1); + | ^ help: replace it with: `w` + +error: named parameter p is used as a positional parameter + --> $DIR/positional_named_format_parameters.rs:54:16 + | +LL | println!("{:.p$}", p = 1); + | ^ help: replace it with: `p` + +error: aborting due to 69 previous errors + diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed index c4c9c8214..57f23bd19 100644 --- a/src/tools/clippy/tests/ui/question_mark.fixed +++ b/src/tools/clippy/tests/ui/question_mark.fixed @@ -207,4 +207,19 @@ fn option_map() -> Option<bool> { } } +pub struct PatternedError { + flag: bool, +} + +// No warning +fn pattern() -> Result<(), PatternedError> { + let res = Ok(()); + + if let Err(err @ PatternedError { flag: true }) = res { + return Err(err); + } + + res +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs index cdbc7b160..436f027c2 100644 --- a/src/tools/clippy/tests/ui/question_mark.rs +++ b/src/tools/clippy/tests/ui/question_mark.rs @@ -243,4 +243,19 @@ fn option_map() -> Option<bool> { } } +pub struct PatternedError { + flag: bool, +} + +// No warning +fn pattern() -> Result<(), PatternedError> { + let res = Ok(()); + + if let Err(err @ PatternedError { flag: true }) = res { + return Err(err); + } + + res +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed index 40d7791df..a16a3e54d 100644 --- a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed +++ b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed @@ -6,6 +6,22 @@ fn f() -> usize { 42 } +macro_rules! macro_plus_one { + ($m: literal) => { + for i in 0..$m + 1 { + println!("{}", i); + } + }; +} + +macro_rules! macro_minus_one { + ($m: literal) => { + for i in 0..=$m - 1 { + println!("{}", i); + } + }; +} + #[warn(clippy::range_plus_one)] #[warn(clippy::range_minus_one)] fn main() { @@ -39,4 +55,7 @@ fn main() { let mut vec: Vec<()> = std::vec::Vec::new(); vec.drain(..); + + macro_plus_one!(5); + macro_minus_one!(5); } diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.rs b/src/tools/clippy/tests/ui/range_plus_minus_one.rs index a8ddd9b5f..bd6cb4d21 100644 --- a/src/tools/clippy/tests/ui/range_plus_minus_one.rs +++ b/src/tools/clippy/tests/ui/range_plus_minus_one.rs @@ -6,6 +6,22 @@ fn f() -> usize { 42 } +macro_rules! macro_plus_one { + ($m: literal) => { + for i in 0..$m + 1 { + println!("{}", i); + } + }; +} + +macro_rules! macro_minus_one { + ($m: literal) => { + for i in 0..=$m - 1 { + println!("{}", i); + } + }; +} + #[warn(clippy::range_plus_one)] #[warn(clippy::range_minus_one)] fn main() { @@ -39,4 +55,7 @@ fn main() { let mut vec: Vec<()> = std::vec::Vec::new(); vec.drain(..); + + macro_plus_one!(5); + macro_minus_one!(5); } diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr index fb4f16585..022369624 100644 --- a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr +++ b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr @@ -1,5 +1,5 @@ error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:15:14 + --> $DIR/range_plus_minus_one.rs:31:14 | LL | for _ in 0..3 + 1 {} | ^^^^^^^^ help: use: `0..=3` @@ -7,25 +7,25 @@ LL | for _ in 0..3 + 1 {} = note: `-D clippy::range-plus-one` implied by `-D warnings` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:18:14 + --> $DIR/range_plus_minus_one.rs:34:14 | LL | for _ in 0..1 + 5 {} | ^^^^^^^^ help: use: `0..=5` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:21:14 + --> $DIR/range_plus_minus_one.rs:37:14 | LL | for _ in 1..1 + 1 {} | ^^^^^^^^ help: use: `1..=1` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:27:14 + --> $DIR/range_plus_minus_one.rs:43:14 | LL | for _ in 0..(1 + f()) {} | ^^^^^^^^^^^^ help: use: `0..=f()` error: an exclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:31:13 + --> $DIR/range_plus_minus_one.rs:47:13 | LL | let _ = ..=11 - 1; | ^^^^^^^^^ help: use: `..11` @@ -33,25 +33,25 @@ LL | let _ = ..=11 - 1; = note: `-D clippy::range-minus-one` implied by `-D warnings` error: an exclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:32:13 + --> $DIR/range_plus_minus_one.rs:48:13 | LL | let _ = ..=(11 - 1); | ^^^^^^^^^^^ help: use: `..11` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:33:13 + --> $DIR/range_plus_minus_one.rs:49:13 | LL | let _ = (1..11 + 1); | ^^^^^^^^^^^ help: use: `(1..=11)` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:34:13 + --> $DIR/range_plus_minus_one.rs:50:13 | LL | let _ = (f() + 1)..(f() + 1); | ^^^^^^^^^^^^^^^^^^^^ help: use: `((f() + 1)..=f())` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:38:14 + --> $DIR/range_plus_minus_one.rs:54:14 | LL | for _ in 1..ONE + ONE {} | ^^^^^^^^^^^^ help: use: `1..=ONE` diff --git a/src/tools/clippy/tests/ui/rc_mutex.rs b/src/tools/clippy/tests/ui/rc_mutex.rs index 18e8a2e01..432972bbc 100644 --- a/src/tools/clippy/tests/ui/rc_mutex.rs +++ b/src/tools/clippy/tests/ui/rc_mutex.rs @@ -1,5 +1,5 @@ #![warn(clippy::rc_mutex)] -#![allow(unused, clippy::blacklisted_name)] +#![allow(unused, clippy::disallowed_names)] use std::rc::Rc; use std::sync::Mutex; diff --git a/src/tools/clippy/tests/ui/redundant_allocation.rs b/src/tools/clippy/tests/ui/redundant_allocation.rs index cf7d8c6e3..574d34aed 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation.rs +++ b/src/tools/clippy/tests/ui/redundant_allocation.rs @@ -1,7 +1,5 @@ #![warn(clippy::all)] -#![allow(clippy::boxed_local, clippy::needless_pass_by_value)] -#![allow(clippy::blacklisted_name, unused_variables, dead_code)] -#![allow(unused_imports)] +#![allow(clippy::boxed_local, clippy::disallowed_names)] pub struct MyStruct; @@ -9,13 +7,7 @@ pub struct SubT<T> { foo: T, } -pub enum MyEnum { - One, - Two, -} - mod outer_box { - use crate::MyEnum; use crate::MyStruct; use crate::SubT; use std::boxed::Box; @@ -36,7 +28,6 @@ mod outer_box { } mod outer_rc { - use crate::MyEnum; use crate::MyStruct; use crate::SubT; use std::boxed::Box; @@ -57,7 +48,6 @@ mod outer_rc { } mod outer_arc { - use crate::MyEnum; use crate::MyStruct; use crate::SubT; use std::boxed::Box; diff --git a/src/tools/clippy/tests/ui/redundant_allocation.stderr b/src/tools/clippy/tests/ui/redundant_allocation.stderr index fab1b069f..54d4d88db 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation.stderr +++ b/src/tools/clippy/tests/ui/redundant_allocation.stderr @@ -1,5 +1,5 @@ error: usage of `Box<Rc<T>>` - --> $DIR/redundant_allocation.rs:25:30 + --> $DIR/redundant_allocation.rs:17:30 | LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {} | ^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {} = help: consider using just `Box<T>` or `Rc<T>` error: usage of `Box<Arc<T>>` - --> $DIR/redundant_allocation.rs:27:30 + --> $DIR/redundant_allocation.rs:19:30 | LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {} | ^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {} = help: consider using just `Box<T>` or `Arc<T>` error: usage of `Box<Rc<SubT<usize>>>` - --> $DIR/redundant_allocation.rs:29:27 + --> $DIR/redundant_allocation.rs:21:27 | LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> { = help: consider using just `Box<SubT<usize>>` or `Rc<SubT<usize>>` error: usage of `Box<Arc<T>>` - --> $DIR/redundant_allocation.rs:33:30 + --> $DIR/redundant_allocation.rs:25:30 | LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> { | ^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> { = help: consider using just `Box<T>` or `Arc<T>` error: usage of `Box<Arc<SubT<T>>>` - --> $DIR/redundant_allocation.rs:33:46 + --> $DIR/redundant_allocation.rs:25:46 | LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> { | ^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> { = help: consider using just `Box<SubT<T>>` or `Arc<SubT<T>>` error: usage of `Rc<Box<bool>>` - --> $DIR/redundant_allocation.rs:46:24 + --> $DIR/redundant_allocation.rs:37:24 | LL | pub fn rc_test5(a: Rc<Box<bool>>) {} | ^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | pub fn rc_test5(a: Rc<Box<bool>>) {} = help: consider using just `Rc<bool>` or `Box<bool>` error: usage of `Rc<Arc<bool>>` - --> $DIR/redundant_allocation.rs:48:24 + --> $DIR/redundant_allocation.rs:39:24 | LL | pub fn rc_test7(a: Rc<Arc<bool>>) {} | ^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | pub fn rc_test7(a: Rc<Arc<bool>>) {} = help: consider using just `Rc<bool>` or `Arc<bool>` error: usage of `Rc<Box<SubT<usize>>>` - --> $DIR/redundant_allocation.rs:50:26 + --> $DIR/redundant_allocation.rs:41:26 | LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> { = help: consider using just `Rc<SubT<usize>>` or `Box<SubT<usize>>` error: usage of `Rc<Arc<T>>` - --> $DIR/redundant_allocation.rs:54:29 + --> $DIR/redundant_allocation.rs:45:29 | LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> { | ^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> { = help: consider using just `Rc<T>` or `Arc<T>` error: usage of `Rc<Arc<SubT<T>>>` - --> $DIR/redundant_allocation.rs:54:44 + --> $DIR/redundant_allocation.rs:45:44 | LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> { | ^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> { = help: consider using just `Rc<SubT<T>>` or `Arc<SubT<T>>` error: usage of `Arc<Box<bool>>` - --> $DIR/redundant_allocation.rs:67:25 + --> $DIR/redundant_allocation.rs:57:25 | LL | pub fn arc_test5(a: Arc<Box<bool>>) {} | ^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | pub fn arc_test5(a: Arc<Box<bool>>) {} = help: consider using just `Arc<bool>` or `Box<bool>` error: usage of `Arc<Rc<bool>>` - --> $DIR/redundant_allocation.rs:69:25 + --> $DIR/redundant_allocation.rs:59:25 | LL | pub fn arc_test6(a: Arc<Rc<bool>>) {} | ^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | pub fn arc_test6(a: Arc<Rc<bool>>) {} = help: consider using just `Arc<bool>` or `Rc<bool>` error: usage of `Arc<Box<SubT<usize>>>` - --> $DIR/redundant_allocation.rs:71:27 + --> $DIR/redundant_allocation.rs:61:27 | LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> { | ^^^^^^^^^^^^^^^^^^^^^ @@ -117,7 +117,7 @@ LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> { = help: consider using just `Arc<SubT<usize>>` or `Box<SubT<usize>>` error: usage of `Arc<Rc<T>>` - --> $DIR/redundant_allocation.rs:75:30 + --> $DIR/redundant_allocation.rs:65:30 | LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> { | ^^^^^^^^^^ @@ -126,7 +126,7 @@ LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> { = help: consider using just `Arc<T>` or `Rc<T>` error: usage of `Arc<Rc<SubT<T>>>` - --> $DIR/redundant_allocation.rs:75:45 + --> $DIR/redundant_allocation.rs:65:45 | LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> { | ^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> { = help: consider using just `Arc<SubT<T>>` or `Rc<SubT<T>>` error: usage of `Rc<Box<Box<dyn T>>>` - --> $DIR/redundant_allocation.rs:97:27 + --> $DIR/redundant_allocation.rs:87:27 | LL | pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {} | ^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {} = help: consider using just `Rc<Box<dyn T>>` or `Box<Box<dyn T>>` error: usage of `Rc<Box<Box<str>>>` - --> $DIR/redundant_allocation.rs:129:31 + --> $DIR/redundant_allocation.rs:119:31 | LL | pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {} | ^^^^^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ LL | pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {} = help: consider using just `Rc<Box<str>>` or `Box<Box<str>>` error: usage of `Rc<Box<Box<[usize]>>>` - --> $DIR/redundant_allocation.rs:130:33 + --> $DIR/redundant_allocation.rs:120:33 | LL | pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {} = help: consider using just `Rc<Box<[usize]>>` or `Box<Box<[usize]>>` error: usage of `Rc<Box<Box<Path>>>` - --> $DIR/redundant_allocation.rs:131:32 + --> $DIR/redundant_allocation.rs:121:32 | LL | pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {} | ^^^^^^^^^^^^^^^^^^ @@ -171,7 +171,7 @@ LL | pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {} = help: consider using just `Rc<Box<Path>>` or `Box<Box<Path>>` error: usage of `Rc<Box<Box<DynSized>>>` - --> $DIR/redundant_allocation.rs:132:34 + --> $DIR/redundant_allocation.rs:122:34 | LL | pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed index e7ed84731..6db02718c 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed +++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed @@ -1,7 +1,7 @@ // run-rustfix #![warn(clippy::all)] #![allow(clippy::boxed_local, clippy::needless_pass_by_value)] -#![allow(clippy::blacklisted_name, unused_variables, dead_code)] +#![allow(clippy::disallowed_names, unused_variables, dead_code)] #![allow(unused_imports)] pub struct MyStruct; diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs index de763f98b..c15806f30 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs +++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs @@ -1,7 +1,7 @@ // run-rustfix #![warn(clippy::all)] #![allow(clippy::boxed_local, clippy::needless_pass_by_value)] -#![allow(clippy::blacklisted_name, unused_variables, dead_code)] +#![allow(clippy::disallowed_names, unused_variables, dead_code)] #![allow(unused_imports)] pub struct MyStruct; diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed index 0abca6fca..7cd687c95 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed @@ -1,8 +1,28 @@ // run-rustfix +#![feature(async_closure)] #![warn(clippy::redundant_closure_call)] #![allow(unused)] +async fn something() -> u32 { + 21 +} + +async fn something_else() -> u32 { + 2 +} + fn main() { let a = 42; + let b = async { + let x = something().await; + let y = something_else().await; + x * y + }; + let c = { + let x = 21; + let y = 2; + x * y + }; + let d = async { something().await }; } diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs index f8b9d37a5..37e4d2238 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs @@ -1,8 +1,28 @@ // run-rustfix +#![feature(async_closure)] #![warn(clippy::redundant_closure_call)] #![allow(unused)] +async fn something() -> u32 { + 21 +} + +async fn something_else() -> u32 { + 2 +} + fn main() { let a = (|| 42)(); + let b = (async || { + let x = something().await; + let y = something_else().await; + x * y + })(); + let c = (|| { + let x = 21; + let y = 2; + x * y + })(); + let d = (async || something().await)(); } diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr index afd704ef1..56a8e57c0 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr @@ -1,10 +1,56 @@ error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:7:13 + --> $DIR/redundant_closure_call_fixable.rs:16:13 | LL | let a = (|| 42)(); | ^^^^^^^^^ help: try doing something like: `42` | = note: `-D clippy::redundant-closure-call` implied by `-D warnings` -error: aborting due to previous error +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:17:13 + | +LL | let b = (async || { + | _____________^ +LL | | let x = something().await; +LL | | let y = something_else().await; +LL | | x * y +LL | | })(); + | |________^ + | +help: try doing something like + | +LL ~ let b = async { +LL + let x = something().await; +LL + let y = something_else().await; +LL + x * y +LL ~ }; + | + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:22:13 + | +LL | let c = (|| { + | _____________^ +LL | | let x = 21; +LL | | let y = 2; +LL | | x * y +LL | | })(); + | |________^ + | +help: try doing something like + | +LL ~ let c = { +LL + let x = 21; +LL + let y = 2; +LL + x * y +LL ~ }; + | + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:27:13 + | +LL | let d = (async || something().await)(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }` + +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs index f7f3b195c..f0e1a8128 100644 --- a/src/tools/clippy/tests/ui/regex.rs +++ b/src/tools/clippy/tests/ui/regex.rs @@ -1,4 +1,4 @@ -#![allow(unused)] +#![allow(unused, clippy::needless_borrow)] #![warn(clippy::invalid_regex, clippy::trivial_regex)] extern crate regex; diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 53288be94..9cbad2269 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -4,6 +4,7 @@ // run-rustfix +#![allow(clippy::disallowed_names)] #![allow(clippy::blocks_in_if_conditions)] #![allow(clippy::box_collection)] #![allow(clippy::redundant_static_lifetimes)] @@ -14,6 +15,7 @@ #![allow(clippy::for_loops_over_fallibles)] #![allow(clippy::useless_conversion)] #![allow(clippy::match_result_ok)] +#![allow(clippy::overly_complex_bool_expr)] #![allow(clippy::new_without_default)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::expect_used)] @@ -33,6 +35,7 @@ #![allow(temporary_cstring_as_ptr)] #![allow(unknown_lints)] #![allow(unused_labels)] +#![warn(clippy::disallowed_names)] #![warn(clippy::blocks_in_if_conditions)] #![warn(clippy::blocks_in_if_conditions)] #![warn(clippy::box_collection)] @@ -45,6 +48,7 @@ #![warn(clippy::for_loops_over_fallibles)] #![warn(clippy::useless_conversion)] #![warn(clippy::match_result_ok)] +#![warn(clippy::overly_complex_bool_expr)] #![warn(clippy::new_without_default)] #![warn(clippy::bind_instead_of_map)] #![warn(clippy::expect_used)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 539f34f84..9153c0dab 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -4,6 +4,7 @@ // run-rustfix +#![allow(clippy::disallowed_names)] #![allow(clippy::blocks_in_if_conditions)] #![allow(clippy::box_collection)] #![allow(clippy::redundant_static_lifetimes)] @@ -14,6 +15,7 @@ #![allow(clippy::for_loops_over_fallibles)] #![allow(clippy::useless_conversion)] #![allow(clippy::match_result_ok)] +#![allow(clippy::overly_complex_bool_expr)] #![allow(clippy::new_without_default)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::expect_used)] @@ -33,6 +35,7 @@ #![allow(temporary_cstring_as_ptr)] #![allow(unknown_lints)] #![allow(unused_labels)] +#![warn(clippy::blacklisted_name)] #![warn(clippy::block_in_if_condition_expr)] #![warn(clippy::block_in_if_condition_stmt)] #![warn(clippy::box_vec)] @@ -45,6 +48,7 @@ #![warn(clippy::for_loop_over_result)] #![warn(clippy::identity_conversion)] #![warn(clippy::if_let_some_result)] +#![warn(clippy::logic_bug)] #![warn(clippy::new_without_default_derive)] #![warn(clippy::option_and_then_some)] #![warn(clippy::option_expect_used)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 8ea46b580..9c03ea914 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,214 +1,226 @@ +error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` + --> $DIR/rename.rs:38:9 + | +LL | #![warn(clippy::blacklisted_name)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` + | + = note: `-D renamed-and-removed-lints` implied by `-D warnings` + error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:36:9 + --> $DIR/rename.rs:39:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` - | - = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:37:9 + --> $DIR/rename.rs:40:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:38:9 + --> $DIR/rename.rs:41:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:39:9 + --> $DIR/rename.rs:42:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:40:9 + --> $DIR/rename.rs:43:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:41:9 + --> $DIR/rename.rs:44:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:42:9 + --> $DIR/rename.rs:45:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:43:9 + --> $DIR/rename.rs:46:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::for_loop_over_option` has been renamed to `clippy::for_loops_over_fallibles` - --> $DIR/rename.rs:44:9 + --> $DIR/rename.rs:47:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `clippy::for_loops_over_fallibles` - --> $DIR/rename.rs:45:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:46:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` +error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` + --> $DIR/rename.rs:51:9 + | +LL | #![warn(clippy::logic_bug)] + | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` + error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 35 previous errors +error: aborting due to 37 previous errors diff --git a/src/tools/clippy/tests/ui/result_large_err.rs b/src/tools/clippy/tests/ui/result_large_err.rs new file mode 100644 index 000000000..f7df3b856 --- /dev/null +++ b/src/tools/clippy/tests/ui/result_large_err.rs @@ -0,0 +1,99 @@ +#![warn(clippy::result_large_err)] +#![allow(clippy::large_enum_variant)] + +pub fn small_err() -> Result<(), u128> { + Ok(()) +} + +pub fn large_err() -> Result<(), [u8; 512]> { + Ok(()) +} + +pub struct FullyDefinedLargeError { + _foo: u128, + _bar: [u8; 100], + _foobar: [u8; 120], +} + +impl FullyDefinedLargeError { + pub fn ret() -> Result<(), Self> { + Ok(()) + } +} + +pub fn struct_error() -> Result<(), FullyDefinedLargeError> { + Ok(()) +} + +type Fdlr<T> = std::result::Result<T, FullyDefinedLargeError>; +pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> { + Ok(x) +} + +pub fn param_small_error<R>() -> Result<(), (R, u128)> { + Ok(()) +} + +pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> { + Ok(()) +} + +pub enum LargeErrorVariants<T> { + _Small(u8), + _Omg([u8; 512]), + _Param(T), +} + +impl LargeErrorVariants<()> { + pub fn large_enum_error() -> Result<(), Self> { + Ok(()) + } +} + +trait TraitForcesLargeError { + fn large_error() -> Result<(), [u8; 512]> { + Ok(()) + } +} + +struct TraitImpl; + +impl TraitForcesLargeError for TraitImpl { + // Should not lint + fn large_error() -> Result<(), [u8; 512]> { + Ok(()) + } +} + +pub union FullyDefinedUnionError { + _maybe: u8, + _or_even: [[u8; 16]; 32], +} + +pub fn large_union_err() -> Result<(), FullyDefinedUnionError> { + Ok(()) +} + +pub union UnionError<T: Copy> { + _maybe: T, + _or_perhaps_even: (T, [u8; 512]), +} + +pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> { + Ok(()) +} + +pub struct ArrayError<T, U> { + _large_array: [T; 32], + _other_stuff: U, +} + +pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> { + Ok(()) +} + +pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> { + Ok(()) +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/result_large_err.stderr b/src/tools/clippy/tests/ui/result_large_err.stderr new file mode 100644 index 000000000..ef19f2854 --- /dev/null +++ b/src/tools/clippy/tests/ui/result_large_err.stderr @@ -0,0 +1,91 @@ +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:8:23 + | +LL | pub fn large_err() -> Result<(), [u8; 512]> { + | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes + | + = note: `-D clippy::result-large-err` implied by `-D warnings` + = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:19:21 + | +LL | pub fn ret() -> Result<(), Self> { + | ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes + | + = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:24:26 + | +LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes + | + = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:29:45 + | +LL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> { + | ^^^^^^^ the `Err`-variant is at least 240 bytes + | + = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:37:34 + | +LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 256 bytes + | + = help: try reducing the size of `(u128, R, FullyDefinedLargeError)`, for example by boxing large elements or replacing it with `Box<(u128, R, FullyDefinedLargeError)>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:48:34 + | +LL | pub fn large_enum_error() -> Result<(), Self> { + | ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 513 bytes + | + = help: try reducing the size of `LargeErrorVariants<()>`, for example by boxing large elements or replacing it with `Box<LargeErrorVariants<()>>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:54:25 + | +LL | fn large_error() -> Result<(), [u8; 512]> { + | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes + | + = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:73:29 + | +LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes + | + = help: try reducing the size of `FullyDefinedUnionError`, for example by boxing large elements or replacing it with `Box<FullyDefinedUnionError>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:82:40 + | +LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes + | + = help: try reducing the size of `UnionError<T>`, for example by boxing large elements or replacing it with `Box<UnionError<T>>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:91:34 + | +LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes + | + = help: try reducing the size of `ArrayError<i32, U>`, for example by boxing large elements or replacing it with `Box<ArrayError<i32, U>>` + +error: the `Err`-variant returned from this function is very large + --> $DIR/result_large_err.rs:95:31 + | +LL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes + | + = help: try reducing the size of `ArrayError<(i32, T), U>`, for example by boxing large elements or replacing it with `Box<ArrayError<(i32, T), U>>` + +error: aborting due to 11 previous errors + diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs index 3d2295912..a48829caa 100644 --- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs +++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs @@ -48,9 +48,9 @@ fn ifs_same_cond_fn() { } let mut v = vec![1]; - if v.pop() == None { + if v.pop().is_none() { //~ ERROR ifs same condition - } else if v.pop() == None { + } else if v.pop().is_none() { } if v.len() == 42 { diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr index 71e82910e..cd438b830 100644 --- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr +++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr @@ -50,14 +50,14 @@ LL | if obj.method_arg(a) { error: this `if` has the same function call as a previous `if` --> $DIR/same_functions_in_if_condition.rs:53:15 | -LL | } else if v.pop() == None { - | ^^^^^^^^^^^^^^^ +LL | } else if v.pop().is_none() { + | ^^^^^^^^^^^^^^^^^ | note: same as this --> $DIR/same_functions_in_if_condition.rs:51:8 | -LL | if v.pop() == None { - | ^^^^^^^^^^^^^^^ +LL | if v.pop().is_none() { + | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` --> $DIR/same_functions_in_if_condition.rs:58:15 diff --git a/src/tools/clippy/tests/ui/same_item_push.rs b/src/tools/clippy/tests/ui/same_item_push.rs index 99964f0de..af01a8df7 100644 --- a/src/tools/clippy/tests/ui/same_item_push.rs +++ b/src/tools/clippy/tests/ui/same_item_push.rs @@ -151,6 +151,7 @@ fn main() { // Fix #6987 let mut vec = Vec::new(); + #[allow(clippy::needless_borrow)] for _ in 0..10 { vec.push(1); vec.extend(&[2]); diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs index 91916e748..c4dfbd921 100644 --- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs +++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs @@ -1,7 +1,5 @@ #![warn(clippy::semicolon_if_nothing_returned)] #![allow(clippy::redundant_closure)] -#![feature(label_break_value)] -#![feature(let_else)] fn get_unit() {} diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr index 41d2c1cfb..8d9a67585 100644 --- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr +++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr @@ -1,5 +1,5 @@ error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:10:5 + --> $DIR/semicolon_if_nothing_returned.rs:8:5 | LL | println!("Hello") | ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!("Hello");` @@ -7,25 +7,25 @@ LL | println!("Hello") = note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:14:5 + --> $DIR/semicolon_if_nothing_returned.rs:12:5 | LL | get_unit() | ^^^^^^^^^^ help: add a `;` here: `get_unit();` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:19:5 + --> $DIR/semicolon_if_nothing_returned.rs:17:5 | LL | y = x + 1 | ^^^^^^^^^ help: add a `;` here: `y = x + 1;` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:25:9 + --> $DIR/semicolon_if_nothing_returned.rs:23:9 | LL | hello() | ^^^^^^^ help: add a `;` here: `hello();` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:36:9 + --> $DIR/semicolon_if_nothing_returned.rs:34:9 | LL | ptr::drop_in_place(s.as_mut_ptr()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());` diff --git a/src/tools/clippy/tests/ui/skip_while_next.rs b/src/tools/clippy/tests/ui/skip_while_next.rs index a522c0f08..a551c19d9 100644 --- a/src/tools/clippy/tests/ui/skip_while_next.rs +++ b/src/tools/clippy/tests/ui/skip_while_next.rs @@ -1,7 +1,7 @@ // aux-build:option_helpers.rs #![warn(clippy::skip_while_next)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] extern crate option_helpers; use option_helpers::IteratorFalsePositives; diff --git a/src/tools/clippy/tests/ui/string_add.rs b/src/tools/clippy/tests/ui/string_add.rs index 30fd17c59..16673c01e 100644 --- a/src/tools/clippy/tests/ui/string_add.rs +++ b/src/tools/clippy/tests/ui/string_add.rs @@ -7,13 +7,13 @@ extern crate macro_rules; #[allow(clippy::string_add_assign, unused)] fn main() { // ignores assignment distinction - let mut x = "".to_owned(); + let mut x = String::new(); for _ in 1..3 { x = x + "."; } - let y = "".to_owned(); + let y = String::new(); let z = y + "..."; assert_eq!(&x, &z); diff --git a/src/tools/clippy/tests/ui/string_add_assign.fixed b/src/tools/clippy/tests/ui/string_add_assign.fixed index db71bab1e..b687f43b2 100644 --- a/src/tools/clippy/tests/ui/string_add_assign.fixed +++ b/src/tools/clippy/tests/ui/string_add_assign.fixed @@ -4,13 +4,13 @@ #[warn(clippy::string_add_assign)] fn main() { // ignores assignment distinction - let mut x = "".to_owned(); + let mut x = String::new(); for _ in 1..3 { x += "."; } - let y = "".to_owned(); + let y = String::new(); let z = y + "..."; assert_eq!(&x, &z); diff --git a/src/tools/clippy/tests/ui/string_add_assign.rs b/src/tools/clippy/tests/ui/string_add_assign.rs index 644991945..e5dbde108 100644 --- a/src/tools/clippy/tests/ui/string_add_assign.rs +++ b/src/tools/clippy/tests/ui/string_add_assign.rs @@ -4,13 +4,13 @@ #[warn(clippy::string_add_assign)] fn main() { // ignores assignment distinction - let mut x = "".to_owned(); + let mut x = String::new(); for _ in 1..3 { x = x + "."; } - let y = "".to_owned(); + let y = String::new(); let z = y + "..."; assert_eq!(&x, &z); diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.rs b/src/tools/clippy/tests/ui/suspicious_to_owned.rs new file mode 100644 index 000000000..cba21bf4a --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_to_owned.rs @@ -0,0 +1,62 @@ +#![warn(clippy::suspicious_to_owned)] +#![warn(clippy::implicit_clone)] +#![allow(clippy::redundant_clone)] +use std::borrow::Cow; +use std::ffi::{c_char, CStr}; + +fn main() { + let moo = "Moooo"; + let c_moo = b"Moooo\0"; + let c_moo_ptr = c_moo.as_ptr() as *const c_char; + let moos = ['M', 'o', 'o']; + let moos_vec = moos.to_vec(); + + // we expect this to be linted + let cow = Cow::Borrowed(moo); + let _ = cow.to_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(moo); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(moo); + let _ = cow.clone(); + + // we expect this to be linted + let cow = Cow::Borrowed(&moos); + let _ = cow.to_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos); + let _ = cow.clone(); + + // we expect this to be linted + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.to_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.clone(); + + // we expect this to be linted + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.to_owned(); + // we expect no lints for this + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.clone(); + + // we expect no lints for these + let _ = moo.to_owned(); + let _ = c_moo.to_owned(); + let _ = moos.to_owned(); + + // we expect implicit_clone lints for these + let _ = String::from(moo).to_owned(); + let _ = moos_vec.to_owned(); +} diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr new file mode 100644 index 000000000..92e1024bf --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr @@ -0,0 +1,42 @@ +error: this `to_owned` call clones the std::borrow::Cow<str> itself and does not cause the std::borrow::Cow<str> contents to become owned + --> $DIR/suspicious_to_owned.rs:16:13 + | +LL | let _ = cow.to_owned(); + | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + | + = note: `-D clippy::suspicious-to-owned` implied by `-D warnings` + +error: this `to_owned` call clones the std::borrow::Cow<[char; 3]> itself and does not cause the std::borrow::Cow<[char; 3]> contents to become owned + --> $DIR/suspicious_to_owned.rs:26:13 + | +LL | let _ = cow.to_owned(); + | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + +error: this `to_owned` call clones the std::borrow::Cow<std::vec::Vec<char>> itself and does not cause the std::borrow::Cow<std::vec::Vec<char>> contents to become owned + --> $DIR/suspicious_to_owned.rs:36:13 + | +LL | let _ = cow.to_owned(); + | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + +error: this `to_owned` call clones the std::borrow::Cow<str> itself and does not cause the std::borrow::Cow<str> contents to become owned + --> $DIR/suspicious_to_owned.rs:46:13 + | +LL | let _ = cow.to_owned(); + | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + +error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type + --> $DIR/suspicious_to_owned.rs:60:13 + | +LL | let _ = String::from(moo).to_owned(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::from(moo).clone()` + | + = note: `-D clippy::implicit-clone` implied by `-D warnings` + +error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type + --> $DIR/suspicious_to_owned.rs:61:13 + | +LL | let _ = moos_vec.to_owned(); + | ^^^^^^^^^^^^^^^^^^^ help: consider using: `moos_vec.clone()` + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/swap.fixed b/src/tools/clippy/tests/ui/swap.fixed index 3329efbd4..24b229235 100644 --- a/src/tools/clippy/tests/ui/swap.fixed +++ b/src/tools/clippy/tests/ui/swap.fixed @@ -2,7 +2,7 @@ #![warn(clippy::all)] #![allow( - clippy::blacklisted_name, + clippy::disallowed_names, clippy::no_effect, clippy::redundant_clone, redundant_semicolons, diff --git a/src/tools/clippy/tests/ui/swap.rs b/src/tools/clippy/tests/ui/swap.rs index 8179ac1f2..a318c2791 100644 --- a/src/tools/clippy/tests/ui/swap.rs +++ b/src/tools/clippy/tests/ui/swap.rs @@ -2,7 +2,7 @@ #![warn(clippy::all)] #![allow( - clippy::blacklisted_name, + clippy::disallowed_names, clippy::no_effect, clippy::redundant_clone, redundant_semicolons, diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed new file mode 100644 index 000000000..4ce5d4217 --- /dev/null +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed @@ -0,0 +1,112 @@ +// run-rustfix +#![deny(clippy::trait_duplication_in_bounds)] +#![allow(unused)] + +fn bad_foo<T: Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) { + unimplemented!(); +} + +fn bad_bar<T, U>(arg0: T, arg1: U) +where + T: Clone + Copy, + U: Clone + Copy, +{ + unimplemented!(); +} + +fn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) { + unimplemented!(); +} + +fn good_foo<T, U>(arg0: T, arg1: U) +where + T: Clone + Copy, + U: Clone + Copy, +{ + unimplemented!(); +} + +trait GoodSelfTraitBound: Clone + Copy { + fn f(); +} + +trait GoodSelfWhereClause { + fn f() + where + Self: Clone + Copy; +} + +trait BadSelfTraitBound: Clone { + fn f(); +} + +trait BadSelfWhereClause { + fn f() + where + Self: Clone; +} + +trait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> { + fn f(); +} + +trait GoodWhereClause<T, U> { + fn f() + where + T: Clone + Copy, + U: Clone + Copy; +} + +trait BadTraitBound<T: Clone + Copy, U: Clone + Copy> { + fn f(); +} + +trait BadWhereClause<T, U> { + fn f() + where + T: Clone + Copy, + U: Clone + Copy; +} + +struct GoodStructBound<T: Clone + Copy, U: Clone + Copy> { + t: T, + u: U, +} + +impl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> { + // this should not warn + fn f() {} +} + +struct GoodStructWhereClause; + +impl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause +where + T: Clone + Copy, + U: Clone + Copy, +{ + // this should not warn + fn f() {} +} + +fn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {} + +trait GenericTrait<T> {} + +fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) { + unimplemented!(); +} + +fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) { + unimplemented!(); +} + +mod foo { + pub trait Clone {} +} + +fn qualified_path<T: std::clone::Clone + foo::Clone>(arg0: T) { + unimplemented!(); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs index a5751c58a..7f2e96a22 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs @@ -1,212 +1,112 @@ +// run-rustfix #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -use std::collections::BTreeMap; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; +fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) { + unimplemented!(); +} -fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) +fn bad_bar<T, U>(arg0: T, arg1: U) where - T: Clone, - T: Default, + T: Clone + Clone + Clone + Copy, + U: Clone + Copy, { unimplemented!(); } -fn good_bar<T: Clone + Default>(arg: T) { +fn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) { unimplemented!(); } -fn good_foo<T>(arg: T) +fn good_foo<T, U>(arg0: T, arg1: U) where - T: Clone + Default, + T: Clone + Copy, + U: Clone + Copy, { unimplemented!(); } -fn good_foobar<T: Default>(arg: T) -where - T: Clone, -{ - unimplemented!(); +trait GoodSelfTraitBound: Clone + Copy { + fn f(); } -trait T: Default { +trait GoodSelfWhereClause { fn f() where - Self: Default; + Self: Clone + Copy; } -trait U: Default { +trait BadSelfTraitBound: Clone + Clone + Clone { + fn f(); +} + +trait BadSelfWhereClause { fn f() where - Self: Clone; + Self: Clone + Clone + Clone; +} + +trait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> { + fn f(); } -trait ZZ: Default { - fn g(); - fn h(); +trait GoodWhereClause<T, U> { fn f() where - Self: Default + Clone; + T: Clone + Copy, + U: Clone + Copy; } -trait BadTrait: Default + Clone { +trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> { + fn f(); +} + +trait BadWhereClause<T, U> { fn f() where - Self: Default + Clone; - fn g() - where - Self: Default; - fn h() - where - Self: Copy; + T: Clone + Clone + Clone + Copy, + U: Clone + Copy; } -#[derive(Default, Clone)] -struct Life; +struct GoodStructBound<T: Clone + Copy, U: Clone + Copy> { + t: T, + u: U, +} -impl T for Life { +impl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> { // this should not warn fn f() {} } -impl U for Life { +struct GoodStructWhereClause; + +impl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause +where + T: Clone + Copy, + U: Clone + Copy, +{ // this should not warn fn f() {} } -// should not warn -trait Iter: Iterator { - fn into_group_btreemap<K, V>(self) -> BTreeMap<K, Vec<V>> - where - Self: Iterator<Item = (K, V)> + Sized, - K: Ord + Eq, - { - unimplemented!(); - } -} +fn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {} -struct Foo; +trait GenericTrait<T> {} -trait FooIter: Iterator<Item = Foo> { - fn bar() - where - Self: Iterator<Item = Foo>, - { - } +fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) { + unimplemented!(); } -// This should not lint -fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {} - -mod repeated_where_clauses_or_trait_bounds { - fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) { - unimplemented!(); - } - - fn bad_bar<T, U>(arg0: T, arg1: U) - where - T: Clone + Clone + Clone + Copy, - U: Clone + Copy, - { - unimplemented!(); - } - - fn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) { - unimplemented!(); - } - - fn good_foo<T, U>(arg0: T, arg1: U) - where - T: Clone + Copy, - U: Clone + Copy, - { - unimplemented!(); - } - - trait GoodSelfTraitBound: Clone + Copy { - fn f(); - } - - trait GoodSelfWhereClause { - fn f() - where - Self: Clone + Copy; - } - - trait BadSelfTraitBound: Clone + Clone + Clone { - fn f(); - } - - trait BadSelfWhereClause { - fn f() - where - Self: Clone + Clone + Clone; - } - - trait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> { - fn f(); - } - - trait GoodWhereClause<T, U> { - fn f() - where - T: Clone + Copy, - U: Clone + Copy; - } - - trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> { - fn f(); - } - - trait BadWhereClause<T, U> { - fn f() - where - T: Clone + Clone + Clone + Copy, - U: Clone + Copy; - } - - struct GoodStructBound<T: Clone + Copy, U: Clone + Copy> { - t: T, - u: U, - } - - impl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> { - // this should not warn - fn f() {} - } - - struct GoodStructWhereClause; - - impl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause - where - T: Clone + Copy, - U: Clone + Copy, - { - // this should not warn - fn f() {} - } - - fn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {} - - trait GenericTrait<T> {} - - // This should not warn but currently does see #8757 - fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) { - unimplemented!(); - } - - fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) { - unimplemented!(); - } +fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) { + unimplemented!(); +} - mod foo { - pub trait Clone {} - } +mod foo { + pub trait Clone {} +} - fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) { - unimplemented!(); - } +fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) { + unimplemented!(); } fn main() {} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr index 7ef04e527..af800ba78 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr @@ -1,167 +1,56 @@ -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:7:15 +error: these bounds contain repeated elements + --> $DIR/trait_duplication_in_bounds.rs:5:15 | -LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) - | ^^^^^ +LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` | note: the lint level is defined here - --> $DIR/trait_duplication_in_bounds.rs:1:9 + --> $DIR/trait_duplication_in_bounds.rs:2:9 | LL | #![deny(clippy::trait_duplication_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: consider removing this trait bound - -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:7:23 - | -LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) - | ^^^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in trait declaration - --> $DIR/trait_duplication_in_bounds.rs:36:15 - | -LL | Self: Default; - | ^^^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in trait declaration - --> $DIR/trait_duplication_in_bounds.rs:50:15 - | -LL | Self: Default + Clone; - | ^^^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in trait declaration - --> $DIR/trait_duplication_in_bounds.rs:56:15 - | -LL | Self: Default + Clone; - | ^^^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in trait declaration - --> $DIR/trait_duplication_in_bounds.rs:56:25 - | -LL | Self: Default + Clone; - | ^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in trait declaration - --> $DIR/trait_duplication_in_bounds.rs:59:15 - | -LL | Self: Default; - | ^^^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in trait declaration - --> $DIR/trait_duplication_in_bounds.rs:94:15 - | -LL | Self: Iterator<Item = Foo>, - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:103:19 - | -LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) { - | ^^^^^ - | - = help: consider removing this trait bound - -error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:103:19 - | -LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` - -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:109:12 - | -LL | T: Clone + Clone + Clone + Copy, - | ^^^^^ - | - = help: consider removing this trait bound error: these where clauses contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:109:12 + --> $DIR/trait_duplication_in_bounds.rs:11:8 | -LL | T: Clone + Clone + Clone + Copy, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` +LL | T: Clone + Clone + Clone + Copy, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:137:30 + --> $DIR/trait_duplication_in_bounds.rs:39:26 | -LL | trait BadSelfTraitBound: Clone + Clone + Clone { - | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` +LL | trait BadSelfTraitBound: Clone + Clone + Clone { + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` error: these where clauses contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:144:19 - | -LL | Self: Clone + Clone + Clone; - | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` - -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:158:28 + --> $DIR/trait_duplication_in_bounds.rs:46:15 | -LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> { - | ^^^^^ - | - = help: consider removing this trait bound +LL | Self: Clone + Clone + Clone; + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:158:28 + --> $DIR/trait_duplication_in_bounds.rs:60:24 | -LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` +LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these where clauses contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:165:16 - | -LL | T: Clone + Clone + Clone + Copy, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` - -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:195:24 - | -LL | fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) { - | ^^^^^^^^^^^^^^^^^ - | - = help: consider removing this trait bound - -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:199:23 + --> $DIR/trait_duplication_in_bounds.rs:67:12 | -LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) { - | ^^^^^^^^^^^^^^^^^ - | - = help: consider removing this trait bound +LL | T: Clone + Clone + Clone + Copy, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:199:23 - | -LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait<u32> + GenericTrait<u64>` - -error: this trait bound is already specified in the where clause - --> $DIR/trait_duplication_in_bounds.rs:207:26 - | -LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) { - | ^^^^^^^^^^^^^^^^^ + --> $DIR/trait_duplication_in_bounds.rs:100:19 | - = help: consider removing this trait bound +LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait<u64> + GenericTrait<u32>` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:207:26 + --> $DIR/trait_duplication_in_bounds.rs:108:22 | -LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + foo::Clone` +LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone` -error: aborting due to 22 previous errors +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs new file mode 100644 index 000000000..5630a0345 --- /dev/null +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs @@ -0,0 +1,166 @@ +#![deny(clippy::trait_duplication_in_bounds)] + +use std::collections::BTreeMap; +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; + +fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) +where + T: Clone, + T: Default, +{ + unimplemented!(); +} + +fn good_bar<T: Clone + Default>(arg: T) { + unimplemented!(); +} + +fn good_foo<T>(arg: T) +where + T: Clone + Default, +{ + unimplemented!(); +} + +fn good_foobar<T: Default>(arg: T) +where + T: Clone, +{ + unimplemented!(); +} + +trait T: Default { + fn f() + where + Self: Default; +} + +trait U: Default { + fn f() + where + Self: Clone; +} + +trait ZZ: Default { + fn g(); + fn h(); + fn f() + where + Self: Default + Clone; +} + +trait BadTrait: Default + Clone { + fn f() + where + Self: Default + Clone; + fn g() + where + Self: Default; + fn h() + where + Self: Copy; +} + +#[derive(Default, Clone)] +struct Life; + +impl T for Life { + // this should not warn + fn f() {} +} + +impl U for Life { + // this should not warn + fn f() {} +} + +// should not warn +trait Iter: Iterator { + fn into_group_btreemap<K, V>(self) -> BTreeMap<K, Vec<V>> + where + Self: Iterator<Item = (K, V)> + Sized, + K: Ord + Eq, + { + unimplemented!(); + } +} + +struct Foo; + +trait FooIter: Iterator<Item = Foo> { + fn bar() + where + Self: Iterator<Item = Foo>, + { + } +} + +// The below should not lint and exist to guard against false positives +fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {} + +pub mod one { + #[derive(Clone, Debug)] + struct MultiProductIter<I> + where + I: Iterator + Clone, + I::Item: Clone, + { + _marker: I, + } + + pub struct MultiProduct<I>(Vec<MultiProductIter<I>>) + where + I: Iterator + Clone, + I::Item: Clone; + + pub fn multi_cartesian_product<H>(_: H) -> MultiProduct<<H::Item as IntoIterator>::IntoIter> + where + H: Iterator, + H::Item: IntoIterator, + <H::Item as IntoIterator>::IntoIter: Clone, + <H::Item as IntoIterator>::Item: Clone, + { + todo!() + } +} + +pub mod two { + use std::iter::Peekable; + + pub struct MergeBy<I, J, F> + where + I: Iterator, + J: Iterator<Item = I::Item>, + { + _i: Peekable<I>, + _j: Peekable<J>, + _f: F, + } + + impl<I, J, F> Clone for MergeBy<I, J, F> + where + I: Iterator, + J: Iterator<Item = I::Item>, + std::iter::Peekable<I>: Clone, + std::iter::Peekable<J>: Clone, + F: Clone, + { + fn clone(&self) -> Self { + Self { + _i: self._i.clone(), + _j: self._j.clone(), + _f: self._f.clone(), + } + } + } +} + +pub trait Trait {} + +pub fn f(_a: impl Trait, _b: impl Trait) {} + +pub trait ImplTrait<T> {} + +impl<A, B> ImplTrait<(A, B)> for Foo where Foo: ImplTrait<A> + ImplTrait<B> {} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr new file mode 100644 index 000000000..fbd9abb00 --- /dev/null +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr @@ -0,0 +1,71 @@ +error: this trait bound is already specified in the where clause + --> $DIR/trait_duplication_in_bounds_unfixable.rs:6:15 + | +LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/trait_duplication_in_bounds_unfixable.rs:1:9 + | +LL | #![deny(clippy::trait_duplication_in_bounds)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider removing this trait bound + +error: this trait bound is already specified in the where clause + --> $DIR/trait_duplication_in_bounds_unfixable.rs:6:23 + | +LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) + | ^^^^^^^ + | + = help: consider removing this trait bound + +error: this trait bound is already specified in trait declaration + --> $DIR/trait_duplication_in_bounds_unfixable.rs:35:15 + | +LL | Self: Default; + | ^^^^^^^ + | + = help: consider removing this trait bound + +error: this trait bound is already specified in trait declaration + --> $DIR/trait_duplication_in_bounds_unfixable.rs:49:15 + | +LL | Self: Default + Clone; + | ^^^^^^^ + | + = help: consider removing this trait bound + +error: this trait bound is already specified in trait declaration + --> $DIR/trait_duplication_in_bounds_unfixable.rs:55:15 + | +LL | Self: Default + Clone; + | ^^^^^^^ + | + = help: consider removing this trait bound + +error: this trait bound is already specified in trait declaration + --> $DIR/trait_duplication_in_bounds_unfixable.rs:55:25 + | +LL | Self: Default + Clone; + | ^^^^^ + | + = help: consider removing this trait bound + +error: this trait bound is already specified in trait declaration + --> $DIR/trait_duplication_in_bounds_unfixable.rs:58:15 + | +LL | Self: Default; + | ^^^^^^^ + | + = help: consider removing this trait bound + +error: this trait bound is already specified in trait declaration + --> $DIR/trait_duplication_in_bounds_unfixable.rs:93:15 + | +LL | Self: Iterator<Item = Foo>, + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: consider removing this trait bound + +error: aborting due to 8 previous errors + diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs index ebcaa7a84..5aad0b442 100644 --- a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs +++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs @@ -4,6 +4,7 @@ use core::any::TypeId; use core::ffi::c_void; use core::mem::{size_of, transmute, MaybeUninit}; +use core::ptr::NonNull; fn value<T>() -> T { unimplemented!() @@ -109,6 +110,17 @@ fn main() { let _: Ty2<u32, u32> = transmute(value::<MaybeUninit<Ty2<u32, u32>>>()); // Ok let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec<u32>>()); // Ok + + let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<Ty2<u32, u32>, u32>>()); // Ok + let _: *const Ty2C<Ty2<u32, u32>, u32> = transmute(value::<*const Ty2<u32, u32>>()); // Ok + let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<(), Ty2<u32, u32>>>()); // Ok + let _: *const Ty2C<(), Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Ok + + let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err + let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err + + let _: NonNull<u8> = transmute(value::<NonNull<(String, String)>>()); // Ok + let _: NonNull<(String, String)> = transmute(value::<NonNull<u8>>()); // Ok } } diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr index 28bfba6c7..e50a77329 100644 --- a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr +++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr @@ -1,5 +1,5 @@ error: transmute from `Ty2<u32, i32>` which has an undefined layout - --> $DIR/transmute_undefined_repr.rs:27:33 + --> $DIR/transmute_undefined_repr.rs:28:33 | LL | let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,13 +7,13 @@ LL | let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lin = note: `-D clippy::transmute-undefined-repr` implied by `-D warnings` error: transmute into `Ty2<u32, i32>` which has an undefined layout - --> $DIR/transmute_undefined_repr.rs:28:32 + --> $DIR/transmute_undefined_repr.rs:29:32 | LL | let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:33:32 + --> $DIR/transmute_undefined_repr.rs:34:32 | LL | let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:34:36 + --> $DIR/transmute_undefined_repr.rs:35:36 | LL | let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `Ty<&Ty2<u32, i32>>` to `&Ty2<u32, f32>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:39:33 + --> $DIR/transmute_undefined_repr.rs:40:33 | LL | let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); / = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `&Ty2<u32, f32>` to `Ty<&Ty2<u32, i32>>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:40:37 + --> $DIR/transmute_undefined_repr.rs:41:37 | LL | let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); / = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `std::boxed::Box<Ty2<u32, u32>>` to `&mut Ty2<u32, f32>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:57:45 + --> $DIR/transmute_undefined_repr.rs:58:45 | LL | let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Lint, different Ty2 instances | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,15 +53,31 @@ LL | let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `&mut Ty2<u32, f32>` to `std::boxed::Box<Ty2<u32, u32>>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:58:37 + --> $DIR/transmute_undefined_repr.rs:59:37 | LL | let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>()); // Lint, different Ty2 instances | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: two instances of the same generic type (`Ty2`) may have different layouts +error: transmute into `*const Ty2<u32, u32>` which has an undefined layout + --> $DIR/transmute_undefined_repr.rs:119:39 + | +LL | let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the contained type `Ty2<u32, u32>` has an undefined layout + +error: transmute from `*const Ty2<u32, u32>` which has an undefined layout + --> $DIR/transmute_undefined_repr.rs:120:50 + | +LL | let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the contained type `Ty2<u32, u32>` has an undefined layout + error: transmute from `std::vec::Vec<Ty2<U, i32>>` to `std::vec::Vec<Ty2<T, u32>>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:138:35 + --> $DIR/transmute_undefined_repr.rs:150:35 | LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); // Err | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,12 +85,12 @@ LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); / = note: two instances of the same generic type (`Vec`) may have different layouts error: transmute from `std::vec::Vec<Ty2<T, u32>>` to `std::vec::Vec<Ty2<U, i32>>`, both of which have an undefined layout - --> $DIR/transmute_undefined_repr.rs:139:35 + --> $DIR/transmute_undefined_repr.rs:151:35 | LL | let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>()); // Err | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: two instances of the same generic type (`Vec`) may have different layouts -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs index 8f78f16a0..c0c64ebca 100644 --- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs +++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs @@ -2,7 +2,7 @@ // normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)" #![deny(clippy::trivially_copy_pass_by_ref)] -#![allow(clippy::blacklisted_name, clippy::redundant_field_names)] +#![allow(clippy::disallowed_names, clippy::redundant_field_names)] #[derive(Copy, Clone)] struct Foo(u32); diff --git a/src/tools/clippy/tests/ui/unicode.fixed b/src/tools/clippy/tests/ui/unicode.fixed index 328cda369..94b472345 100644 --- a/src/tools/clippy/tests/ui/unicode.fixed +++ b/src/tools/clippy/tests/ui/unicode.fixed @@ -1,4 +1,7 @@ // run-rustfix +// compile-flags: --test +#![allow(dead_code)] + #[warn(clippy::invisible_characters)] fn zero() { print!("Here >\u{200B}< is a ZWS, and \u{200B}another"); @@ -15,22 +18,43 @@ fn canon() { print!("a\u{0300}h?"); // also ok } -#[warn(clippy::non_ascii_literal)] -fn uni() { - print!("\u{dc}ben!"); - print!("\u{DC}ben!"); // this is ok -} +mod non_ascii_literal { + #![deny(clippy::non_ascii_literal)] + + fn uni() { + print!("\u{dc}ben!"); + print!("\u{DC}ben!"); // this is ok + } + + // issue 8013 + fn single_quote() { + const _EMPTY_BLOCK: char = '\u{25b1}'; + const _FULL_BLOCK: char = '\u{25b0}'; + } + + #[test] + pub fn issue_7739() { + // Ryū crate: https://github.com/dtolnay/ryu + } + + mod issue_8263 { + #![deny(clippy::non_ascii_literal)] + + // Re-allow for a single test + #[test] + #[allow(clippy::non_ascii_literal)] + fn allowed() { + let _ = "悲しいかな、ここに日本語を書くことはできない。"; + } -// issue 8013 -#[warn(clippy::non_ascii_literal)] -fn single_quote() { - const _EMPTY_BLOCK: char = '\u{25b1}'; - const _FULL_BLOCK: char = '\u{25b0}'; + #[test] + fn denied() { + let _ = "\u{60b2}\u{3057}\u{3044}\u{304b}\u{306a}\u{3001}\u{3053}\u{3053}\u{306b}\u{65e5}\u{672c}\u{8a9e}\u{3092}\u{66f8}\u{304f}\u{3053}\u{3068}\u{306f}\u{3067}\u{304d}\u{306a}\u{3044}\u{3002}"; + } + } } fn main() { zero(); - uni(); canon(); - single_quote(); } diff --git a/src/tools/clippy/tests/ui/unicode.rs b/src/tools/clippy/tests/ui/unicode.rs index 7828d6bcb..6ad0b255b 100644 --- a/src/tools/clippy/tests/ui/unicode.rs +++ b/src/tools/clippy/tests/ui/unicode.rs @@ -1,4 +1,7 @@ // run-rustfix +// compile-flags: --test +#![allow(dead_code)] + #[warn(clippy::invisible_characters)] fn zero() { print!("Here >< is a ZWS, and another"); @@ -15,22 +18,43 @@ fn canon() { print!("a\u{0300}h?"); // also ok } -#[warn(clippy::non_ascii_literal)] -fn uni() { - print!("Üben!"); - print!("\u{DC}ben!"); // this is ok -} +mod non_ascii_literal { + #![deny(clippy::non_ascii_literal)] + + fn uni() { + print!("Üben!"); + print!("\u{DC}ben!"); // this is ok + } + + // issue 8013 + fn single_quote() { + const _EMPTY_BLOCK: char = '▱'; + const _FULL_BLOCK: char = '▰'; + } + + #[test] + pub fn issue_7739() { + // Ryū crate: https://github.com/dtolnay/ryu + } + + mod issue_8263 { + #![deny(clippy::non_ascii_literal)] + + // Re-allow for a single test + #[test] + #[allow(clippy::non_ascii_literal)] + fn allowed() { + let _ = "悲しいかな、ここに日本語を書くことはできない。"; + } -// issue 8013 -#[warn(clippy::non_ascii_literal)] -fn single_quote() { - const _EMPTY_BLOCK: char = '▱'; - const _FULL_BLOCK: char = '▰'; + #[test] + fn denied() { + let _ = "悲しいかな、ここに日本語を書くことはできない。"; + } + } } fn main() { zero(); - uni(); canon(); - single_quote(); } diff --git a/src/tools/clippy/tests/ui/unicode.stderr b/src/tools/clippy/tests/ui/unicode.stderr index 01d3f3c02..ea74a8145 100644 --- a/src/tools/clippy/tests/ui/unicode.stderr +++ b/src/tools/clippy/tests/ui/unicode.stderr @@ -1,5 +1,5 @@ error: invisible character detected - --> $DIR/unicode.rs:4:12 + --> $DIR/unicode.rs:7:12 | LL | print!("Here >< is a ZWS, and another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{200B}< is a ZWS, and /u{200B}another"` @@ -7,19 +7,19 @@ LL | print!("Here >< is a ZWS, and another"); = note: `-D clippy::invisible-characters` implied by `-D warnings` error: invisible character detected - --> $DIR/unicode.rs:6:12 + --> $DIR/unicode.rs:9:12 | LL | print!("Here >< is a SHY, and another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{AD}< is a SHY, and /u{AD}another"` error: invisible character detected - --> $DIR/unicode.rs:8:12 + --> $DIR/unicode.rs:11:12 | LL | print!("Here >< is a WJ, and another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{2060}< is a WJ, and /u{2060}another"` error: non-NFC Unicode sequence detected - --> $DIR/unicode.rs:14:12 + --> $DIR/unicode.rs:17:12 | LL | print!("̀àh?"); | ^^^^^ help: consider replacing the string with: `"̀àh?"` @@ -27,24 +27,40 @@ LL | print!("̀àh?"); = note: `-D clippy::unicode-not-nfc` implied by `-D warnings` error: literal non-ASCII character detected - --> $DIR/unicode.rs:20:12 + --> $DIR/unicode.rs:25:16 | -LL | print!("Üben!"); - | ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"` +LL | print!("Üben!"); + | ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"` | - = note: `-D clippy::non-ascii-literal` implied by `-D warnings` +note: the lint level is defined here + --> $DIR/unicode.rs:22:13 + | +LL | #![deny(clippy::non_ascii_literal)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: literal non-ASCII character detected + --> $DIR/unicode.rs:31:36 + | +LL | const _EMPTY_BLOCK: char = '▱'; + | ^^^ help: consider replacing the string with: `'/u{25b1}'` error: literal non-ASCII character detected - --> $DIR/unicode.rs:27:32 + --> $DIR/unicode.rs:32:35 | -LL | const _EMPTY_BLOCK: char = '▱'; - | ^^^ help: consider replacing the string with: `'/u{25b1}'` +LL | const _FULL_BLOCK: char = '▰'; + | ^^^ help: consider replacing the string with: `'/u{25b0}'` error: literal non-ASCII character detected - --> $DIR/unicode.rs:28:31 + --> $DIR/unicode.rs:52:21 + | +LL | let _ = "悲しいかな、ここに日本語を書くことはできない。"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"/u{60b2}/u{3057}/u{3044}/u{304b}/u{306a}/u{3001}/u{3053}/u{3053}/u{306b}/u{65e5}/u{672c}/u{8a9e}/u{3092}/u{66f8}/u{304f}/u{3053}/u{3068}/u{306f}/u{3067}/u{304d}/u{306a}/u{3044}/u{3002}"` + | +note: the lint level is defined here + --> $DIR/unicode.rs:41:17 | -LL | const _FULL_BLOCK: char = '▰'; - | ^^^ help: consider replacing the string with: `'/u{25b0}'` +LL | #![deny(clippy::non_ascii_literal)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/uninit.rs b/src/tools/clippy/tests/ui/uninit.rs index dac5ce272..211317317 100644 --- a/src/tools/clippy/tests/ui/uninit.rs +++ b/src/tools/clippy/tests/ui/uninit.rs @@ -1,5 +1,5 @@ #![feature(stmt_expr_attributes)] -#![allow(clippy::let_unit_value)] +#![allow(clippy::let_unit_value, invalid_value)] use std::mem::{self, MaybeUninit}; diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs index 38be87bdd..7bf3adc07 100644 --- a/src/tools/clippy/tests/ui/unit_arg.rs +++ b/src/tools/clippy/tests/ui/unit_arg.rs @@ -1,3 +1,5 @@ +// aux-build: proc_macro_with_span.rs + #![warn(clippy::unit_arg)] #![allow( clippy::no_effect, @@ -8,9 +10,13 @@ clippy::or_fun_call, clippy::needless_question_mark, clippy::self_named_constructors, - clippy::let_unit_value + clippy::let_unit_value, + clippy::never_loop )] +extern crate proc_macro_with_span; + +use proc_macro_with_span::with_span; use std::fmt::Debug; fn foo<T: Debug>(t: T) { @@ -127,6 +133,10 @@ fn returning_expr() -> Option<()> { fn taking_multiple_units(a: (), b: ()) {} +fn proc_macro() { + with_span!(span taking_multiple_units(unsafe { (); }, 'x: loop { break 'x (); })); +} + fn main() { bad(); ok(); diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr index 11cfe66a3..1de9d44bb 100644 --- a/src/tools/clippy/tests/ui/unit_arg.stderr +++ b/src/tools/clippy/tests/ui/unit_arg.stderr @@ -1,5 +1,5 @@ error: passing a unit value to a function - --> $DIR/unit_arg.rs:57:5 + --> $DIR/unit_arg.rs:63:5 | LL | / foo({ LL | | 1; @@ -20,7 +20,7 @@ LL ~ foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:60:5 + --> $DIR/unit_arg.rs:66:5 | LL | foo(foo(1)); | ^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL ~ foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:61:5 + --> $DIR/unit_arg.rs:67:5 | LL | / foo({ LL | | foo(1); @@ -54,7 +54,7 @@ LL ~ foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:66:5 + --> $DIR/unit_arg.rs:72:5 | LL | / b.bar({ LL | | 1; @@ -74,7 +74,7 @@ LL ~ b.bar(()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:69:5 + --> $DIR/unit_arg.rs:75:5 | LL | taking_multiple_units(foo(0), foo(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -87,7 +87,7 @@ LL ~ taking_multiple_units((), ()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:70:5 + --> $DIR/unit_arg.rs:76:5 | LL | / taking_multiple_units(foo(0), { LL | | foo(1); @@ -110,7 +110,7 @@ LL ~ taking_multiple_units((), ()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:74:5 + --> $DIR/unit_arg.rs:80:5 | LL | / taking_multiple_units( LL | | { @@ -146,7 +146,7 @@ LL ~ ); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:85:13 + --> $DIR/unit_arg.rs:91:13 | LL | None.or(Some(foo(2))); | ^^^^^^^^^^^^ @@ -160,7 +160,7 @@ LL ~ }); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:88:5 + --> $DIR/unit_arg.rs:94:5 | LL | foo(foo(())); | ^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL ~ foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:125:5 + --> $DIR/unit_arg.rs:131:5 | LL | Some(foo(1)) | ^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.fixed b/src/tools/clippy/tests/ui/unnecessary_cast.fixed index b352b285c..ee9f15734 100644 --- a/src/tools/clippy/tests/ui/unnecessary_cast.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_cast.fixed @@ -88,4 +88,13 @@ mod fixable { } type I32Alias = i32; + + fn issue_9380() { + let _: i32 = -1_i32; + let _: f32 = -(1) as f32; + let _: i64 = -1_i64; + let _: i64 = -(1.0) as i64; + + let _ = -(1 + 1) as i64; + } } diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs index 6c8cc3eff..5b7041242 100644 --- a/src/tools/clippy/tests/ui/unnecessary_cast.rs +++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs @@ -88,4 +88,13 @@ mod fixable { } type I32Alias = i32; + + fn issue_9380() { + let _: i32 = -(1) as i32; + let _: f32 = -(1) as f32; + let _: i64 = -(1) as i64; + let _: i64 = -(1.0) as i64; + + let _ = -(1 + 1) as i64; + } } diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.stderr b/src/tools/clippy/tests/ui/unnecessary_cast.stderr index bad45f002..f7829ff3b 100644 --- a/src/tools/clippy/tests/ui/unnecessary_cast.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_cast.stderr @@ -150,5 +150,17 @@ error: casting float literal to `f32` is unnecessary LL | let _ = -1.0 as f32; | ^^^^^^^^^^^ help: try: `-1.0_f32` -error: aborting due to 25 previous errors +error: casting integer literal to `i32` is unnecessary + --> $DIR/unnecessary_cast.rs:93:22 + | +LL | let _: i32 = -(1) as i32; + | ^^^^^^^^^^^ help: try: `-1_i32` + +error: casting integer literal to `i64` is unnecessary + --> $DIR/unnecessary_cast.rs:95:22 + | +LL | let _: i64 = -(1) as i64; + | ^^^^^^^^^^^ help: try: `-1_i64` + +error: aborting due to 27 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed index f95f91329..40052c410 100644 --- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed @@ -12,6 +12,7 @@ fn main() { ref_str_argument(""); // should be linted + #[allow(clippy::manual_string_new)] ref_str_argument(""); // should not be linted diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs index 0cbdc151e..2304dff51 100644 --- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs +++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs @@ -12,6 +12,7 @@ fn main() { ref_str_argument(&String::new()); // should be linted + #[allow(clippy::manual_string_new)] ref_str_argument(&String::from("")); // should not be linted diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr index 46bc4597b..1eb198a86 100644 --- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr @@ -7,7 +7,7 @@ LL | ref_str_argument(&String::new()); = note: `-D clippy::unnecessary-owned-empty-strings` implied by `-D warnings` error: usage of `&String::from("")` for a function expecting a `&str` argument - --> $DIR/unnecessary_owned_empty_strings.rs:15:22 + --> $DIR/unnecessary_owned_empty_strings.rs:16:22 | LL | ref_str_argument(&String::from("")); | ^^^^^^^^^^^^^^^^^ help: try: `""` diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed index f4f76cd3d..a920c63b1 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed @@ -329,3 +329,91 @@ mod issue_8759_variant { rw.set_view(&rw.default_view().to_owned()); } } + +mod issue_9317 { + #![allow(dead_code)] + + struct Bytes {} + + impl ToString for Bytes { + fn to_string(&self) -> String { + "123".to_string() + } + } + + impl AsRef<[u8]> for Bytes { + fn as_ref(&self) -> &[u8] { + &[1, 2, 3] + } + } + + fn consume<C: AsRef<[u8]>>(c: C) { + let _ = c; + } + + pub fn main() { + let b = Bytes {}; + // Should not lint. + consume(b.to_string()); + } +} + +mod issue_9351 { + #![allow(dead_code)] + + use std::ops::Deref; + use std::path::{Path, PathBuf}; + + fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T { + x + } + + fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {} + + fn id<T: AsRef<str>>(x: T) -> T { + x + } + + fn predicates_are_satisfied(_x: impl std::fmt::Write) {} + + // Should lint + fn single_return() -> impl AsRef<str> { + id("abc") + } + + // Should not lint + fn multiple_returns(b: bool) -> impl AsRef<str> { + if b { + return String::new(); + } + + id("abc".to_string()) + } + + struct S1(String); + + // Should not lint + fn fields1() -> S1 { + S1(id("abc".to_string())) + } + + struct S2 { + s: String, + } + + // Should not lint + fn fields2() { + let mut s = S2 { s: "abc".into() }; + s.s = id("abc".to_string()); + } + + pub fn main() { + let path = std::path::Path::new("x"); + let path_buf = path.to_owned(); + + // Should not lint. + let _x: PathBuf = require_deref_path(path.to_owned()); + generic_arg_used_elsewhere(path.to_owned(), path_buf); + predicates_are_satisfied(id("abc".to_string())); + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs index fe09a489a..2128bdacd 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs @@ -329,3 +329,91 @@ mod issue_8759_variant { rw.set_view(&rw.default_view().to_owned()); } } + +mod issue_9317 { + #![allow(dead_code)] + + struct Bytes {} + + impl ToString for Bytes { + fn to_string(&self) -> String { + "123".to_string() + } + } + + impl AsRef<[u8]> for Bytes { + fn as_ref(&self) -> &[u8] { + &[1, 2, 3] + } + } + + fn consume<C: AsRef<[u8]>>(c: C) { + let _ = c; + } + + pub fn main() { + let b = Bytes {}; + // Should not lint. + consume(b.to_string()); + } +} + +mod issue_9351 { + #![allow(dead_code)] + + use std::ops::Deref; + use std::path::{Path, PathBuf}; + + fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T { + x + } + + fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {} + + fn id<T: AsRef<str>>(x: T) -> T { + x + } + + fn predicates_are_satisfied(_x: impl std::fmt::Write) {} + + // Should lint + fn single_return() -> impl AsRef<str> { + id("abc".to_string()) + } + + // Should not lint + fn multiple_returns(b: bool) -> impl AsRef<str> { + if b { + return String::new(); + } + + id("abc".to_string()) + } + + struct S1(String); + + // Should not lint + fn fields1() -> S1 { + S1(id("abc".to_string())) + } + + struct S2 { + s: String, + } + + // Should not lint + fn fields2() { + let mut s = S2 { s: "abc".into() }; + s.s = id("abc".to_string()); + } + + pub fn main() { + let path = std::path::Path::new("x"); + let path_buf = path.to_owned(); + + // Should not lint. + let _x: PathBuf = require_deref_path(path.to_owned()); + generic_arg_used_elsewhere(path.to_owned(), path_buf); + predicates_are_satisfied(id("abc".to_string())); + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr index 243b4599d..7deb90b06 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr @@ -509,5 +509,11 @@ error: unnecessary use of `to_string` LL | Box::new(build(y.to_string())) | ^^^^^^^^^^^^^ help: use: `y` -error: aborting due to 78 previous errors +error: unnecessary use of `to_string` + --> $DIR/unnecessary_to_owned.rs:381:12 + | +LL | id("abc".to_string()) + | ^^^^^^^^^^^^^^^^^ help: use: `"abc"` + +error: aborting due to 79 previous errors diff --git a/src/tools/clippy/tests/ui/unused_peekable.rs b/src/tools/clippy/tests/ui/unused_peekable.rs new file mode 100644 index 000000000..153457e36 --- /dev/null +++ b/src/tools/clippy/tests/ui/unused_peekable.rs @@ -0,0 +1,144 @@ +#![warn(clippy::unused_peekable)] +#![allow(clippy::no_effect)] + +use std::iter::Empty; +use std::iter::Peekable; + +fn main() { + invalid(); + valid(); +} + +#[allow(clippy::unused_unit)] +fn invalid() { + let peekable = std::iter::empty::<u32>().peekable(); + + // Only lint `new_local` + let old_local = std::iter::empty::<u32>().peekable(); + let new_local = old_local; + + // Behind mut ref + let mut by_mut_ref_test = std::iter::empty::<u32>().peekable(); + let by_mut_ref = &mut by_mut_ref_test; + + // Explicitly returns `Peekable` + fn returns_peekable() -> Peekable<Empty<u32>> { + std::iter::empty().peekable() + } + + let peekable_from_fn = returns_peekable(); + + // Using a method not exclusive to `Peekable` + let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable(); + peekable_using_iterator_method.next(); + + // Passed by ref to another function + fn takes_ref(_peek: &Peekable<Empty<u32>>) {} + let passed_along_ref = std::iter::empty::<u32>().peekable(); + takes_ref(&passed_along_ref); + + // `by_ref` without `peek` + let mut by_ref_test = std::iter::empty::<u32>().peekable(); + let _by_ref = by_ref_test.by_ref(); + + let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable(); + for x in peekable_in_for_loop {} +} + +fn valid() { + fn takes_peekable(_peek: Peekable<Empty<u32>>) {} + + // Passed to another function + let passed_along = std::iter::empty::<u32>().peekable(); + takes_peekable(passed_along); + + // Passed to another method + struct PeekableConsumer; + impl PeekableConsumer { + fn consume(&self, _: Peekable<Empty<u32>>) {} + fn consume_mut_ref(&self, _: &mut Peekable<Empty<u32>>) {} + } + + let peekable_consumer = PeekableConsumer; + let mut passed_along_to_method = std::iter::empty::<u32>().peekable(); + peekable_consumer.consume_mut_ref(&mut passed_along_to_method); + peekable_consumer.consume(passed_along_to_method); + + // `peek` called in another block + let mut peekable_in_block = std::iter::empty::<u32>().peekable(); + { + peekable_in_block.peek(); + } + + // Check the other `Peekable` methods :) + { + let mut peekable_with_peek_mut = std::iter::empty::<u32>().peekable(); + peekable_with_peek_mut.peek_mut(); + + let mut peekable_with_next_if = std::iter::empty::<u32>().peekable(); + peekable_with_next_if.next_if(|_| true); + + let mut peekable_with_next_if_eq = std::iter::empty::<u32>().peekable(); + peekable_with_next_if_eq.next_if_eq(&3); + } + + let mut peekable_in_closure = std::iter::empty::<u32>().peekable(); + let call_peek = |p: &mut Peekable<Empty<u32>>| { + p.peek(); + }; + call_peek(&mut peekable_in_closure); + + // From a macro + macro_rules! make_me_a_peekable_please { + () => { + std::iter::empty::<u32>().peekable() + }; + } + + let _unsuspecting_macro_user = make_me_a_peekable_please!(); + + // Generic Iterator returned + fn return_an_iter() -> impl Iterator<Item = u32> { + std::iter::empty::<u32>().peekable() + } + + let _unsuspecting_user = return_an_iter(); + + // Call `peek` in a macro + macro_rules! peek_iter { + ($iter:ident) => { + $iter.peek(); + }; + } + + let mut peek_in_macro = std::iter::empty::<u32>().peekable(); + peek_iter!(peek_in_macro); + + // Behind mut ref + let mut by_mut_ref_test = std::iter::empty::<u32>().peekable(); + let by_mut_ref = &mut by_mut_ref_test; + by_mut_ref.peek(); + + // Behind ref + let mut by_ref_test = std::iter::empty::<u32>().peekable(); + let by_ref = &by_ref_test; + by_ref_test.peek(); + + // In struct + struct PeekableWrapper { + f: Peekable<Empty<u32>>, + } + + let struct_test = std::iter::empty::<u32>().peekable(); + PeekableWrapper { f: struct_test }; + + // `by_ref` before `peek` + let mut by_ref_test = std::iter::empty::<u32>().peekable(); + let peeked_val = by_ref_test.by_ref().peek(); + + // `peek` called in another block as the last expression + let mut peekable_last_expr = std::iter::empty::<u32>().peekable(); + { + peekable_last_expr.peek(); + } +} diff --git a/src/tools/clippy/tests/ui/unused_peekable.stderr b/src/tools/clippy/tests/ui/unused_peekable.stderr new file mode 100644 index 000000000..d557f5417 --- /dev/null +++ b/src/tools/clippy/tests/ui/unused_peekable.stderr @@ -0,0 +1,67 @@ +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:14:9 + | +LL | let peekable = std::iter::empty::<u32>().peekable(); + | ^^^^^^^^ + | + = note: `-D clippy::unused-peekable` implied by `-D warnings` + = help: consider removing the call to `peekable` + +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:18:9 + | +LL | let new_local = old_local; + | ^^^^^^^^^ + | + = help: consider removing the call to `peekable` + +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:22:9 + | +LL | let by_mut_ref = &mut by_mut_ref_test; + | ^^^^^^^^^^ + | + = help: consider removing the call to `peekable` + +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:29:9 + | +LL | let peekable_from_fn = returns_peekable(); + | ^^^^^^^^^^^^^^^^ + | + = help: consider removing the call to `peekable` + +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:32:13 + | +LL | let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider removing the call to `peekable` + +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:37:9 + | +LL | let passed_along_ref = std::iter::empty::<u32>().peekable(); + | ^^^^^^^^^^^^^^^^ + | + = help: consider removing the call to `peekable` + +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:42:9 + | +LL | let _by_ref = by_ref_test.by_ref(); + | ^^^^^^^ + | + = help: consider removing the call to `peekable` + +error: `peek` never called on `Peekable` iterator + --> $DIR/unused_peekable.rs:44:13 + | +LL | let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: consider removing the call to `peekable` + +error: aborting due to 8 previous errors + diff --git a/src/tools/clippy/tests/ui/unwrap.rs b/src/tools/clippy/tests/ui/unwrap.rs index a4a3cd1d3..d9fd402e7 100644 --- a/src/tools/clippy/tests/ui/unwrap.rs +++ b/src/tools/clippy/tests/ui/unwrap.rs @@ -6,8 +6,9 @@ fn unwrap_option() { } fn unwrap_result() { - let res: Result<u8, ()> = Ok(0); + let res: Result<u8, u8> = Ok(0); let _ = res.unwrap(); + let _ = res.unwrap_err(); } fn main() { diff --git a/src/tools/clippy/tests/ui/unwrap.stderr b/src/tools/clippy/tests/ui/unwrap.stderr index 4f0858005..784227578 100644 --- a/src/tools/clippy/tests/ui/unwrap.stderr +++ b/src/tools/clippy/tests/ui/unwrap.stderr @@ -15,5 +15,13 @@ LL | let _ = res.unwrap(); | = help: if you don't want to handle the `Err` case gracefully, consider using `expect()` to provide a better panic message -error: aborting due to 2 previous errors +error: used `unwrap_err()` on `a Result` value + --> $DIR/unwrap.rs:11:13 + | +LL | let _ = res.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `Ok` case gracefully, consider using `expect_err()` to provide a better panic message + +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.rs b/src/tools/clippy/tests/ui/unwrap_expect_used.rs new file mode 100644 index 000000000..9f27fef82 --- /dev/null +++ b/src/tools/clippy/tests/ui/unwrap_expect_used.rs @@ -0,0 +1,35 @@ +#![warn(clippy::unwrap_used, clippy::expect_used)] + +trait OptionExt { + type Item; + + fn unwrap_err(self) -> Self::Item; + + fn expect_err(self, msg: &str) -> Self::Item; +} + +impl<T> OptionExt for Option<T> { + type Item = T; + fn unwrap_err(self) -> T { + panic!(); + } + + fn expect_err(self, msg: &str) -> T { + panic!(); + } +} + +fn main() { + Some(3).unwrap(); + Some(3).expect("Hello world!"); + + // Don't trigger on unwrap_err on an option + Some(3).unwrap_err(); + Some(3).expect_err("Hellow none!"); + + let a: Result<i32, i32> = Ok(3); + a.unwrap(); + a.expect("Hello world!"); + a.unwrap_err(); + a.expect_err("Hello error!"); +} diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr new file mode 100644 index 000000000..1a19459b2 --- /dev/null +++ b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr @@ -0,0 +1,52 @@ +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_expect_used.rs:23:5 + | +LL | Some(3).unwrap(); + | ^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unwrap-used` implied by `-D warnings` + = help: if this value is `None`, it will panic + +error: used `expect()` on `an Option` value + --> $DIR/unwrap_expect_used.rs:24:5 + | +LL | Some(3).expect("Hello world!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::expect-used` implied by `-D warnings` + = help: if this value is `None`, it will panic + +error: used `unwrap()` on `a Result` value + --> $DIR/unwrap_expect_used.rs:31:5 + | +LL | a.unwrap(); + | ^^^^^^^^^^ + | + = help: if this value is an `Err`, it will panic + +error: used `expect()` on `a Result` value + --> $DIR/unwrap_expect_used.rs:32:5 + | +LL | a.expect("Hello world!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if this value is an `Err`, it will panic + +error: used `unwrap_err()` on `a Result` value + --> $DIR/unwrap_expect_used.rs:33:5 + | +LL | a.unwrap_err(); + | ^^^^^^^^^^^^^^ + | + = help: if this value is an `Ok`, it will panic + +error: used `expect_err()` on `a Result` value + --> $DIR/unwrap_expect_used.rs:34:5 + | +LL | a.expect_err("Hello error!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if this value is an `Ok`, it will panic + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed index c2b9bd2c8..84f779569 100644 --- a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed +++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed @@ -69,6 +69,9 @@ fn unwrap_or_else_default() { let with_default_type: Option<Vec<u64>> = None; with_default_type.unwrap_or_default(); + + let empty_string = None::<String>; + empty_string.unwrap_or_default(); } fn main() {} diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs index d55664990..1735bd580 100644 --- a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs +++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs @@ -69,6 +69,9 @@ fn unwrap_or_else_default() { let with_default_type: Option<Vec<u64>> = None; with_default_type.unwrap_or_else(Vec::new); + + let empty_string = None::<String>; + empty_string.unwrap_or_else(|| "".to_string()); } fn main() {} diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr b/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr index 53e31d85e..d2b921222 100644 --- a/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr +++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr @@ -30,5 +30,11 @@ error: use of `.unwrap_or_else(..)` to construct default value LL | with_default_type.unwrap_or_else(Vec::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_default_type.unwrap_or_default()` -error: aborting due to 5 previous errors +error: use of `.unwrap_or_else(..)` to construct default value + --> $DIR/unwrap_or_else_default.rs:74:5 + | +LL | empty_string.unwrap_or_else(|| "".to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `empty_string.unwrap_or_default()` + +error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.rs b/src/tools/clippy/tests/ui/used_underscore_binding.rs index d20977d55..322083511 100644 --- a/src/tools/clippy/tests/ui/used_underscore_binding.rs +++ b/src/tools/clippy/tests/ui/used_underscore_binding.rs @@ -2,7 +2,7 @@ #![feature(rustc_private)] #![warn(clippy::all)] -#![allow(clippy::blacklisted_name, clippy::eq_op)] +#![allow(clippy::disallowed_names, clippy::eq_op)] #![warn(clippy::used_underscore_binding)] #[macro_use] diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.rs b/src/tools/clippy/tests/ui/useless_conversion_try.rs index 39f54c27b..4acf5b5fa 100644 --- a/src/tools/clippy/tests/ui/useless_conversion_try.rs +++ b/src/tools/clippy/tests/ui/useless_conversion_try.rs @@ -29,10 +29,10 @@ fn main() { let _ = String::try_from("foo".to_string()).unwrap(); let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); let _: String = format!("Hello {}", "world").try_into().unwrap(); - let _: String = "".to_owned().try_into().unwrap(); + let _: String = String::new().try_into().unwrap(); let _: String = match String::from("_").try_into() { Ok(a) => a, - Err(_) => "".into(), + Err(_) => String::new(), }; // FIXME this is a false negative #[allow(clippy::cmp_owned)] diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.stderr b/src/tools/clippy/tests/ui/useless_conversion_try.stderr index b691c13f7..12e74d614 100644 --- a/src/tools/clippy/tests/ui/useless_conversion_try.stderr +++ b/src/tools/clippy/tests/ui/useless_conversion_try.stderr @@ -62,7 +62,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); error: useless conversion to the same type: `std::string::String` --> $DIR/useless_conversion_try.rs:32:21 | -LL | let _: String = "".to_owned().try_into().unwrap(); +LL | let _: String = String::new().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider removing `.try_into()` diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.rs b/src/tools/clippy/tests/ui/vec_resize_to_zero.rs index 7ed27439e..a8307e741 100644 --- a/src/tools/clippy/tests/ui/vec_resize_to_zero.rs +++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.rs @@ -1,15 +1,19 @@ #![warn(clippy::vec_resize_to_zero)] fn main() { + let mut v = vec![1, 2, 3, 4, 5]; + // applicable here - vec![1, 2, 3, 4, 5].resize(0, 5); + v.resize(0, 5); // not applicable - vec![1, 2, 3, 4, 5].resize(2, 5); + v.resize(2, 5); + + let mut v = vec!["foo", "bar", "baz"]; // applicable here, but only implemented for integer literals for now - vec!["foo", "bar", "baz"].resize(0, "bar"); + v.resize(0, "bar"); // not applicable - vec!["foo", "bar", "baz"].resize(2, "bar") + v.resize(2, "bar") } diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr index feb846298..7428cf62d 100644 --- a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr +++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr @@ -1,10 +1,10 @@ error: emptying a vector with `resize` - --> $DIR/vec_resize_to_zero.rs:5:5 + --> $DIR/vec_resize_to_zero.rs:7:5 | -LL | vec![1, 2, 3, 4, 5].resize(0, 5); - | ^^^^^^^^^^^^^^^^^^^^------------ - | | - | help: ...or you can empty the vector with: `clear()` +LL | v.resize(0, 5); + | ^^------------ + | | + | help: ...or you can empty the vector with: `clear()` | = note: `-D clippy::vec-resize-to-zero` implied by `-D warnings` = help: the arguments may be inverted... diff --git a/src/tools/clippy/tests/ui/verbose_file_reads.rs b/src/tools/clippy/tests/ui/verbose_file_reads.rs index e0065e05a..df267e987 100644 --- a/src/tools/clippy/tests/ui/verbose_file_reads.rs +++ b/src/tools/clippy/tests/ui/verbose_file_reads.rs @@ -18,7 +18,7 @@ fn main() -> std::io::Result<()> { s.read_to_end(); s.read_to_string(); // Should catch this - let mut f = File::open(&path)?; + let mut f = File::open(path)?; let mut buffer = Vec::new(); f.read_to_end(&mut buffer)?; // ...and this |