From 197b444407b86b1990f4051b1cb28181e45eb965 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 16 Jul 2024 17:45:22 -0400 Subject: [PATCH] Ignore underscore-prefixed args for needless_pass_by_value lint When a user explicitly tags a param as unused (yet?), there is no need to raise another lint on it. --- clippy_lints/src/needless_pass_by_value.rs | 15 ++++++++------- tests/ui/needless_pass_by_value.rs | 12 ++++++++---- tests/ui/needless_pass_by_value.stderr | 10 +++++----- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index f2e00cef7e9..4b86db33fde 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -129,7 +129,7 @@ fn check_fn( }) .collect::>(); - // Collect moved variables and spans which will need dereferencings from the + // Collect moved variables and spans which will need dereferencing from the // function body. let MovedVariablesCtxt { moved_vars } = { let mut ctx = MovedVariablesCtxt::default(); @@ -148,12 +148,13 @@ fn check_fn( return; } - // Ignore `self`s. - if idx == 0 { - if let PatKind::Binding(.., ident, _) = arg.pat.kind { - if ident.name == kw::SelfLower { - continue; - } + // Ignore `self`s and params whose variable name starts with an underscore + if let PatKind::Binding(.., ident, _) = arg.pat.kind { + if idx == 0 && ident.name == kw::SelfLower { + continue; + } + if ident.name.as_str().starts_with('_') { + continue; } } diff --git a/tests/ui/needless_pass_by_value.rs b/tests/ui/needless_pass_by_value.rs index 14cba5a7eb5..9408b8c948f 100644 --- a/tests/ui/needless_pass_by_value.rs +++ b/tests/ui/needless_pass_by_value.rs @@ -84,7 +84,7 @@ trait Serialize {} impl<'a, T> Serialize for &'a T where T: Serialize {} impl Serialize for i32 {} -fn test_blanket_ref(_foo: T, _serializable: S) {} +fn test_blanket_ref(vals: T, serializable: S) {} //~^ ERROR: this argument is passed by value, but not consumed in the function body fn issue_2114(s: String, t: String, u: Vec, v: Vec) { @@ -116,7 +116,7 @@ fn bar(_t: T, // Ok, since `&T: Serialize` too ) { } - fn baz(&self, _u: U, _s: Self) {} + fn baz(&self, uu: U, ss: Self) {} //~^ ERROR: this argument is passed by value, but not consumed in the function body //~| ERROR: this argument is passed by value, but not consumed in the function body } @@ -162,13 +162,13 @@ fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { // The following 3 lines should not cause an ICE. See #2831 trait Bar<'a, A> {} impl<'b, T> Bar<'b, T> for T {} -fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {} +fn some_fun<'b, S: Bar<'b, ()>>(items: S) {} //~^ ERROR: this argument is passed by value, but not consumed in the function body // Also this should not cause an ICE. See #2831 trait Club<'a, A> {} impl Club<'static, T> for T {} -fn more_fun(_item: impl Club<'static, i32>) {} +fn more_fun(items: impl Club<'static, i32>) {} //~^ ERROR: this argument is passed by value, but not consumed in the function body fn is_sync(_: T) @@ -177,6 +177,10 @@ fn is_sync(_: T) { } +struct Obj(String); + +fn prefix_test(_unused_with_prefix: Obj) {} + fn main() { // This should not cause an ICE either // https://github.com/rust-lang/rust-clippy/issues/3144 diff --git a/tests/ui/needless_pass_by_value.stderr b/tests/ui/needless_pass_by_value.stderr index 827a200ba68..dce28186ff8 100644 --- a/tests/ui/needless_pass_by_value.stderr +++ b/tests/ui/needless_pass_by_value.stderr @@ -46,7 +46,7 @@ LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) { error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:87:49 | -LL | fn test_blanket_ref(_foo: T, _serializable: S) {} +LL | fn test_blanket_ref(vals: T, serializable: S) {} | ^ help: consider taking a reference instead: `&T` error: this argument is passed by value, but not consumed in the function body @@ -106,13 +106,13 @@ LL | t: String, error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:119:23 | -LL | fn baz(&self, _u: U, _s: Self) {} +LL | fn baz(&self, uu: U, ss: Self) {} | ^ help: consider taking a reference instead: `&U` error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:119:30 | -LL | fn baz(&self, _u: U, _s: Self) {} +LL | fn baz(&self, uu: U, ss: Self) {} | ^^^^ help: consider taking a reference instead: `&Self` error: this argument is passed by value, but not consumed in the function body @@ -166,13 +166,13 @@ LL | struct CopyWrapper(u32); error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:165:40 | -LL | fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {} +LL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {} | ^ help: consider taking a reference instead: `&S` error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:171:20 | -LL | fn more_fun(_item: impl Club<'static, i32>) {} +LL | fn more_fun(items: impl Club<'static, i32>) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>` error: aborting due to 22 previous errors