Skip to content

Commit 003e910

Browse files
committed
Auto merge of rust-lang#11817 - y21:ptr_arg_mut_ref, r=Alexendoo
[`ptr_arg`]: recognize methods that also exist on slices Fixes rust-lang#11816 Not a new lint, just a very small improvement to the existing `ptr_arg` lint which would have caught the linked issue. The problem was that the lint checks if a `Vec`-specific method was called, that is, if the receiver is `Vec<_>`. This is the case for `len` and `is_empty`, however these methods also exist on slices so we can still lint there. This logic exists in a different lint, so we can just reuse that here. Interestingly, there was even a comment up top that explained what it should have been doing, but the logic for it just wasn't there? changelog: [`ptr_arg`]: recognize methods that also exist on slices <sub>Also, this is my 100th PR to clippy 🎉 </sub>
2 parents caa7394 + 3e83a52 commit 003e910

File tree

7 files changed

+67
-48
lines changed

7 files changed

+67
-48
lines changed

clippy_lints/src/ptr.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use rustc_trait_selection::infer::InferCtxtExt as _;
2828
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
2929
use std::{fmt, iter};
3030

31+
use crate::vec::is_allowed_vec_method;
32+
3133
declare_clippy_lint! {
3234
/// ### What it does
3335
/// This lint checks for function arguments of type `&String`, `&Vec`,
@@ -660,7 +662,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
660662
},
661663
// If the types match check for methods which exist on both types. e.g. `Vec::len` and
662664
// `slice::len`
663-
ty::Adt(def, _) if def.did() == args.ty_did => {
665+
ty::Adt(def, _) if def.did() == args.ty_did && !is_allowed_vec_method(self.cx, e) => {
664666
set_skip_flag();
665667
},
666668
_ => (),

clippy_lints/src/vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
5757
/// Checks if the given expression is a method call to a `Vec` method
5858
/// that also exists on slices. If this returns true, it means that
5959
/// this expression does not actually require a `Vec` and could just work with an array.
60-
fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
60+
pub fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
6161
const ALLOWED_METHOD_NAMES: &[&str] = &["len", "as_ptr", "is_empty"];
6262

6363
if let ExprKind::MethodCall(path, ..) = e.kind {

lintcheck/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ impl Crate {
309309
target_dir_index: &AtomicUsize,
310310
total_crates_to_lint: usize,
311311
config: &LintcheckConfig,
312-
lint_filter: &Vec<String>,
312+
lint_filter: &[String],
313313
server: &Option<LintcheckServer>,
314314
) -> Vec<ClippyWarning> {
315315
// advance the atomic index by one
@@ -728,7 +728,7 @@ fn read_stats_from_file(file_path: &Path) -> HashMap<String, usize> {
728728
}
729729

730730
/// print how lint counts changed between runs
731-
fn print_stats(old_stats: HashMap<String, usize>, new_stats: HashMap<&String, usize>, lint_filter: &Vec<String>) {
731+
fn print_stats(old_stats: HashMap<String, usize>, new_stats: HashMap<&String, usize>, lint_filter: &[String]) {
732732
let same_in_both_hashmaps = old_stats
733733
.iter()
734734
.filter(|(old_key, old_val)| new_stats.get::<&String>(old_key) == Some(old_val))

tests/ui/needless_pass_by_ref_mut.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
#![allow(clippy::if_same_then_else, clippy::no_effect, clippy::redundant_closure_call)]
1+
#![allow(
2+
clippy::if_same_then_else,
3+
clippy::no_effect,
4+
clippy::redundant_closure_call,
5+
clippy::ptr_arg
6+
)]
27
#![warn(clippy::needless_pass_by_ref_mut)]
38
#![feature(lint_reasons)]
49
//@no-rustfix

tests/ui/needless_pass_by_ref_mut.stderr

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this argument is a mutable reference, but not used mutably
2-
--> $DIR/needless_pass_by_ref_mut.rs:7:11
2+
--> $DIR/needless_pass_by_ref_mut.rs:12:11
33
|
44
LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
55
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
@@ -8,131 +8,131 @@ LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
88
= help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
99

1010
error: this argument is a mutable reference, but not used mutably
11-
--> $DIR/needless_pass_by_ref_mut.rs:32:12
11+
--> $DIR/needless_pass_by_ref_mut.rs:37:12
1212
|
1313
LL | fn foo6(s: &mut Vec<u32>) {
1414
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
1515

1616
error: this argument is a mutable reference, but not used mutably
17-
--> $DIR/needless_pass_by_ref_mut.rs:45:29
17+
--> $DIR/needless_pass_by_ref_mut.rs:50:29
1818
|
1919
LL | fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
2020
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
2121

2222
error: this argument is a mutable reference, but not used mutably
23-
--> $DIR/needless_pass_by_ref_mut.rs:50:31
23+
--> $DIR/needless_pass_by_ref_mut.rs:55:31
2424
|
2525
LL | fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
2626
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
2727

2828
error: this argument is a mutable reference, but not used mutably
29-
--> $DIR/needless_pass_by_ref_mut.rs:127:16
29+
--> $DIR/needless_pass_by_ref_mut.rs:132:16
3030
|
3131
LL | async fn a1(x: &mut i32) {
3232
| ^^^^^^^^ help: consider changing to: `&i32`
3333

3434
error: this argument is a mutable reference, but not used mutably
35-
--> $DIR/needless_pass_by_ref_mut.rs:131:16
35+
--> $DIR/needless_pass_by_ref_mut.rs:136:16
3636
|
3737
LL | async fn a2(x: &mut i32, y: String) {
3838
| ^^^^^^^^ help: consider changing to: `&i32`
3939

4040
error: this argument is a mutable reference, but not used mutably
41-
--> $DIR/needless_pass_by_ref_mut.rs:135:16
41+
--> $DIR/needless_pass_by_ref_mut.rs:140:16
4242
|
4343
LL | async fn a3(x: &mut i32, y: String, z: String) {
4444
| ^^^^^^^^ help: consider changing to: `&i32`
4545

4646
error: this argument is a mutable reference, but not used mutably
47-
--> $DIR/needless_pass_by_ref_mut.rs:139:16
47+
--> $DIR/needless_pass_by_ref_mut.rs:144:16
4848
|
4949
LL | async fn a4(x: &mut i32, y: i32) {
5050
| ^^^^^^^^ help: consider changing to: `&i32`
5151

5252
error: this argument is a mutable reference, but not used mutably
53-
--> $DIR/needless_pass_by_ref_mut.rs:143:24
53+
--> $DIR/needless_pass_by_ref_mut.rs:148:24
5454
|
5555
LL | async fn a5(x: i32, y: &mut i32) {
5656
| ^^^^^^^^ help: consider changing to: `&i32`
5757

5858
error: this argument is a mutable reference, but not used mutably
59-
--> $DIR/needless_pass_by_ref_mut.rs:147:24
59+
--> $DIR/needless_pass_by_ref_mut.rs:152:24
6060
|
6161
LL | async fn a6(x: i32, y: &mut i32) {
6262
| ^^^^^^^^ help: consider changing to: `&i32`
6363

6464
error: this argument is a mutable reference, but not used mutably
65-
--> $DIR/needless_pass_by_ref_mut.rs:151:32
65+
--> $DIR/needless_pass_by_ref_mut.rs:156:32
6666
|
6767
LL | async fn a7(x: i32, y: i32, z: &mut i32) {
6868
| ^^^^^^^^ help: consider changing to: `&i32`
6969

7070
error: this argument is a mutable reference, but not used mutably
71-
--> $DIR/needless_pass_by_ref_mut.rs:155:24
71+
--> $DIR/needless_pass_by_ref_mut.rs:160:24
7272
|
7373
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
7474
| ^^^^^^^^ help: consider changing to: `&i32`
7575

7676
error: this argument is a mutable reference, but not used mutably
77-
--> $DIR/needless_pass_by_ref_mut.rs:155:45
77+
--> $DIR/needless_pass_by_ref_mut.rs:160:45
7878
|
7979
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
8080
| ^^^^^^^^ help: consider changing to: `&i32`
8181

8282
error: this argument is a mutable reference, but not used mutably
83-
--> $DIR/needless_pass_by_ref_mut.rs:189:16
83+
--> $DIR/needless_pass_by_ref_mut.rs:194:16
8484
|
8585
LL | fn cfg_warn(s: &mut u32) {}
8686
| ^^^^^^^^ help: consider changing to: `&u32`
8787
|
8888
= note: this is cfg-gated and may require further changes
8989

9090
error: this argument is a mutable reference, but not used mutably
91-
--> $DIR/needless_pass_by_ref_mut.rs:195:20
91+
--> $DIR/needless_pass_by_ref_mut.rs:200:20
9292
|
9393
LL | fn cfg_warn(s: &mut u32) {}
9494
| ^^^^^^^^ help: consider changing to: `&u32`
9595
|
9696
= note: this is cfg-gated and may require further changes
9797

9898
error: this argument is a mutable reference, but not used mutably
99-
--> $DIR/needless_pass_by_ref_mut.rs:209:39
99+
--> $DIR/needless_pass_by_ref_mut.rs:214:39
100100
|
101101
LL | async fn inner_async2(x: &mut i32, y: &mut u32) {
102102
| ^^^^^^^^ help: consider changing to: `&u32`
103103

104104
error: this argument is a mutable reference, but not used mutably
105-
--> $DIR/needless_pass_by_ref_mut.rs:217:26
105+
--> $DIR/needless_pass_by_ref_mut.rs:222:26
106106
|
107107
LL | async fn inner_async3(x: &mut i32, y: &mut u32) {
108108
| ^^^^^^^^ help: consider changing to: `&i32`
109109

110110
error: this argument is a mutable reference, but not used mutably
111-
--> $DIR/needless_pass_by_ref_mut.rs:236:34
111+
--> $DIR/needless_pass_by_ref_mut.rs:241:34
112112
|
113113
LL | pub async fn call_in_closure1(n: &mut str) {
114114
| ^^^^^^^^ help: consider changing to: `&str`
115115
|
116116
= warning: changing this function will impact semver compatibility
117117

118118
error: this argument is a mutable reference, but not used mutably
119-
--> $DIR/needless_pass_by_ref_mut.rs:248:25
119+
--> $DIR/needless_pass_by_ref_mut.rs:253:25
120120
|
121121
LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
122122
| ^^^^^^^^^^ help: consider changing to: `&usize`
123123
|
124124
= warning: changing this function will impact semver compatibility
125125

126126
error: this argument is a mutable reference, but not used mutably
127-
--> $DIR/needless_pass_by_ref_mut.rs:255:20
127+
--> $DIR/needless_pass_by_ref_mut.rs:260:20
128128
|
129129
LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
130130
| ^^^^^^^^^^ help: consider changing to: `&usize`
131131
|
132132
= warning: changing this function will impact semver compatibility
133133

134134
error: this argument is a mutable reference, but not used mutably
135-
--> $DIR/needless_pass_by_ref_mut.rs:266:26
135+
--> $DIR/needless_pass_by_ref_mut.rs:271:26
136136
|
137137
LL | pub async fn closure4(n: &mut usize) {
138138
| ^^^^^^^^^^ help: consider changing to: `&usize`

tests/ui/ptr_arg.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ fn do_vec_mut(x: &mut Vec<i64>) {
2222
//Nothing here
2323
}
2424

25+
fn do_vec_mut2(x: &mut Vec<i64>) {
26+
//~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w
27+
x.len();
28+
x.is_empty();
29+
}
30+
2531
fn do_str(x: &String) {
2632
//~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d
2733
//Nothing here either

0 commit comments

Comments
 (0)