Skip to content

Commit 2d36728

Browse files
committed
fixup! Fix ptr_arg suggests changes when it's actually better not to bother
changelog: fix false positive: [`ptr_arg`] no longer triggers with underscore binding to `&T` or &mut T` argument
1 parent a78eeb3 commit 2d36728

File tree

3 files changed

+61
-58
lines changed

3 files changed

+61
-58
lines changed

clippy_lints/src/ptr.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -586,9 +586,10 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[
586586
// Only trace simple bindings. e.g `let x = y;`
587587
if let PatKind::Binding(BindingMode::NONE, id, ident, None) = l.pat.kind
588588
// Let's not lint for the current parameter. The user may still intend to mutate
589-
// the referenced value behind the parameter through this local let binding with
590-
// the underscore being temporary.
591-
&& !(ident.name.as_str().starts_with('_') && args.mutability() == Mutability::Mut)
589+
// (or, if not mutate, then perhaps call a method that's not otherwise available
590+
// for) the referenced value behind the parameter through this local let binding
591+
// with the underscore being only temporary.
592+
&& !ident.name.as_str().starts_with('_')
592593
{
593594
self.bindings.insert(id, args_idx);
594595
} else {
@@ -656,10 +657,12 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[
656657
let param = &body.params[arg.idx];
657658
match param.pat.kind {
658659
PatKind::Binding(BindingMode::NONE, id, ident, None)
660+
if !is_lint_allowed(cx, PTR_ARG, param.hir_id)
659661
// Let's not lint for the current parameter. The user may still intend to mutate
660-
// the referenced value behind the parameter with the underscore being temporary.
661-
if !(ident.name.as_str().starts_with('_') && arg.mutability() == Mutability::Mut
662-
|| is_lint_allowed(cx, PTR_ARG, param.hir_id)) =>
662+
// (or, if not mutate, then perhaps call a method that's not otherwise available
663+
// for) the referenced value behind the parameter with the underscore being only
664+
// temporary.
665+
&& !ident.name.as_str().starts_with('_') =>
663666
{
664667
Some((id, i))
665668
},

tests/ui/ptr_arg.rs

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fn test_cow_with_ref(c: &Cow<[i32]>) {}
123123
//~^ ptr_arg
124124

125125
fn test_cow(c: Cow<[i32]>) {
126-
let _c = c;
126+
let d = c;
127127
}
128128

129129
trait Foo2 {
@@ -141,36 +141,36 @@ mod issue_5644 {
141141
use std::path::PathBuf;
142142

143143
fn allowed(
144-
#[allow(clippy::ptr_arg)] _v: &Vec<u32>,
145-
#[allow(clippy::ptr_arg)] _s: &String,
146-
#[allow(clippy::ptr_arg)] _p: &PathBuf,
147-
#[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
148-
#[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
144+
#[allow(clippy::ptr_arg)] v: &Vec<u32>,
145+
#[allow(clippy::ptr_arg)] s: &String,
146+
#[allow(clippy::ptr_arg)] p: &PathBuf,
147+
#[allow(clippy::ptr_arg)] c: &Cow<[i32]>,
148+
#[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,
149149
) {
150150
}
151151

152-
fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
152+
fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &String) {}
153153
//~^ ptr_arg
154154

155155
struct S;
156156
impl S {
157157
fn allowed(
158-
#[allow(clippy::ptr_arg)] _v: &Vec<u32>,
159-
#[allow(clippy::ptr_arg)] _s: &String,
160-
#[allow(clippy::ptr_arg)] _p: &PathBuf,
161-
#[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
162-
#[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
158+
#[allow(clippy::ptr_arg)] v: &Vec<u32>,
159+
#[allow(clippy::ptr_arg)] s: &String,
160+
#[allow(clippy::ptr_arg)] p: &PathBuf,
161+
#[allow(clippy::ptr_arg)] c: &Cow<[i32]>,
162+
#[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,
163163
) {
164164
}
165165
}
166166

167167
trait T {
168168
fn allowed(
169-
#[allow(clippy::ptr_arg)] _v: &Vec<u32>,
170-
#[allow(clippy::ptr_arg)] _s: &String,
171-
#[allow(clippy::ptr_arg)] _p: &PathBuf,
172-
#[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
173-
#[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
169+
#[allow(clippy::ptr_arg)] v: &Vec<u32>,
170+
#[allow(clippy::ptr_arg)] s: &String,
171+
#[allow(clippy::ptr_arg)] p: &PathBuf,
172+
#[allow(clippy::ptr_arg)] c: &Cow<[i32]>,
173+
#[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,
174174
) {
175175
}
176176
}
@@ -182,22 +182,22 @@ mod issue6509 {
182182
fn foo_vec(vec: &Vec<u8>) {
183183
//~^ ptr_arg
184184

185-
let _ = vec.clone().pop();
186-
let _ = vec.clone().clone();
185+
let a = vec.clone().pop();
186+
let b = vec.clone().clone();
187187
}
188188

189189
fn foo_path(path: &PathBuf) {
190190
//~^ ptr_arg
191191

192-
let _ = path.clone().pop();
193-
let _ = path.clone().clone();
192+
let c = path.clone().pop();
193+
let d = path.clone().clone();
194194
}
195195

196196
fn foo_str(str: &PathBuf) {
197197
//~^ ptr_arg
198198

199-
let _ = str.clone().pop();
200-
let _ = str.clone().clone();
199+
let e = str.clone().pop();
200+
let f = str.clone().clone();
201201
}
202202
}
203203

@@ -340,8 +340,8 @@ mod issue_13308 {
340340
ToOwned::clone_into(source, destination);
341341
}
342342

343-
fn h1(_: &<String as Deref>::Target) {}
344-
fn h2<T: Deref>(_: T, _: &T::Target) {}
343+
fn h1(x: &<String as Deref>::Target) {}
344+
fn h2<T: Deref>(x: T, y: &T::Target) {}
345345

346346
// Other cases that are still ok to lint and ideally shouldn't regress
347347
fn good(v1: &String, v2: &String) {
@@ -353,28 +353,28 @@ mod issue_13308 {
353353
}
354354
}
355355

356-
mod issue_13489 {
356+
mod issue_13489_and_13728 {
357357
// This is a no-lint from now on.
358-
fn foo(_x: &mut Vec<i32>) {
358+
fn foo(_x: &Vec<i32>) {
359359
todo!();
360360
}
361361

362362
// But this still gives us a lint.
363-
fn foo_used(x: &mut Vec<i32>) {
363+
fn foo_used(x: &Vec<i32>) {
364364
//~^ ptr_arg
365365

366366
todo!();
367367
}
368368

369369
// This is also a no-lint from now on.
370-
fn foo_local(x: &mut Vec<i32>) {
370+
fn foo_local(x: &Vec<i32>) {
371371
let _y = x;
372372

373373
todo!();
374374
}
375375

376376
// But this still gives us a lint.
377-
fn foo_local_used(x: &mut Vec<i32>) {
377+
fn foo_local_used(x: &Vec<i32>) {
378378
//~^ ptr_arg
379379

380380
let y = x;
@@ -383,21 +383,21 @@ mod issue_13489 {
383383
}
384384

385385
// This only lints once from now on.
386-
fn foofoo(_x: &mut Vec<i32>, y: &mut String) {
386+
fn foofoo(_x: &Vec<i32>, y: &String) {
387387
//~^ ptr_arg
388388

389389
todo!();
390390
}
391391

392392
// And this is also a no-lint from now on.
393-
fn foofoo_local(_x: &mut Vec<i32>, y: &mut String) {
393+
fn foofoo_local(_x: &Vec<i32>, y: &String) {
394394
let _z = y;
395395

396396
todo!();
397397
}
398398
}
399399

400-
mod issue_13728 {
400+
mod issue_13489_and_13728_mut {
401401
// This is a no-lint from now on.
402402
fn bar(_x: &mut Vec<u32>) {
403403
todo!()

tests/ui/ptr_arg.stderr

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ LL | fn test_cow_with_ref(c: &Cow<[i32]>) {}
127127
| ^^^^^^^^^^^ help: change this to: `&[i32]`
128128

129129
error: writing `&String` instead of `&str` involves a new object where a slice will do
130-
--> tests/ui/ptr_arg.rs:152:66
130+
--> tests/ui/ptr_arg.rs:152:64
131131
|
132-
LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
133-
| ^^^^^^^ help: change this to: `&str`
132+
LL | fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &String) {}
133+
| ^^^^^^^ help: change this to: `&str`
134134

135135
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
136136
--> tests/ui/ptr_arg.rs:182:21
@@ -143,8 +143,8 @@ help: change this to
143143
LL ~ fn foo_vec(vec: &[u8]) {
144144
LL |
145145
LL |
146-
LL ~ let _ = vec.to_owned().pop();
147-
LL ~ let _ = vec.to_owned().clone();
146+
LL ~ let a = vec.to_owned().pop();
147+
LL ~ let b = vec.to_owned().clone();
148148
|
149149

150150
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
@@ -158,8 +158,8 @@ help: change this to
158158
LL ~ fn foo_path(path: &Path) {
159159
LL |
160160
LL |
161-
LL ~ let _ = path.to_path_buf().pop();
162-
LL ~ let _ = path.to_path_buf().clone();
161+
LL ~ let c = path.to_path_buf().pop();
162+
LL ~ let d = path.to_path_buf().clone();
163163
|
164164

165165
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
@@ -173,8 +173,8 @@ help: change this to
173173
LL ~ fn foo_str(str: &Path) {
174174
LL |
175175
LL |
176-
LL ~ let _ = str.to_path_buf().pop();
177-
LL ~ let _ = str.to_path_buf().clone();
176+
LL ~ let e = str.to_path_buf().pop();
177+
LL ~ let f = str.to_path_buf().clone();
178178
|
179179

180180
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
@@ -231,23 +231,23 @@ error: writing `&String` instead of `&str` involves a new object where a slice w
231231
LL | fn good(v1: &String, v2: &String) {
232232
| ^^^^^^^ help: change this to: `&str`
233233

234-
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
234+
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
235235
--> tests/ui/ptr_arg.rs:363:20
236236
|
237-
LL | fn foo_used(x: &mut Vec<i32>) {
238-
| ^^^^^^^^^^^^^ help: change this to: `&mut [i32]`
237+
LL | fn foo_used(x: &Vec<i32>) {
238+
| ^^^^^^^^^ help: change this to: `&[i32]`
239239

240-
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
240+
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
241241
--> tests/ui/ptr_arg.rs:377:26
242242
|
243-
LL | fn foo_local_used(x: &mut Vec<i32>) {
244-
| ^^^^^^^^^^^^^ help: change this to: `&mut [i32]`
243+
LL | fn foo_local_used(x: &Vec<i32>) {
244+
| ^^^^^^^^^ help: change this to: `&[i32]`
245245

246-
error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do
247-
--> tests/ui/ptr_arg.rs:386:37
246+
error: writing `&String` instead of `&str` involves a new object where a slice will do
247+
--> tests/ui/ptr_arg.rs:386:33
248248
|
249-
LL | fn foofoo(_x: &mut Vec<i32>, y: &mut String) {
250-
| ^^^^^^^^^^^ help: change this to: `&mut str`
249+
LL | fn foofoo(_x: &Vec<i32>, y: &String) {
250+
| ^^^^^^^ help: change this to: `&str`
251251

252252
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
253253
--> tests/ui/ptr_arg.rs:407:20

0 commit comments

Comments
 (0)