[ptr_arg
]: recognize methods that also exist on slices
This commit is contained in:
parent
abf01e469b
commit
bb694615b8
@ -29,6 +29,8 @@
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use std::{fmt, iter};
|
||||
|
||||
use crate::vec::is_allowed_vec_method;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// This lint checks for function arguments of type `&String`, `&Vec`,
|
||||
@ -661,7 +663,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
|
||||
},
|
||||
// If the types match check for methods which exist on both types. e.g. `Vec::len` and
|
||||
// `slice::len`
|
||||
ty::Adt(def, _) if def.did() == args.ty_did => {
|
||||
ty::Adt(def, _) if def.did() == args.ty_did && !is_allowed_vec_method(self.cx, e) => {
|
||||
set_skip_flag();
|
||||
},
|
||||
_ => (),
|
||||
|
@ -58,7 +58,7 @@ fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
/// Checks if the given expression is a method call to a `Vec` method
|
||||
/// that also exists on slices. If this returns true, it means that
|
||||
/// this expression does not actually require a `Vec` and could just work with an array.
|
||||
fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
pub fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
const ALLOWED_METHOD_NAMES: &[&str] = &["len", "as_ptr", "is_empty"];
|
||||
|
||||
if let ExprKind::MethodCall(path, ..) = e.kind {
|
||||
|
@ -1,4 +1,9 @@
|
||||
#![allow(clippy::if_same_then_else, clippy::no_effect, clippy::redundant_closure_call)]
|
||||
#![allow(
|
||||
clippy::if_same_then_else,
|
||||
clippy::no_effect,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::ptr_arg
|
||||
)]
|
||||
#![warn(clippy::needless_pass_by_ref_mut)]
|
||||
#![feature(lint_reasons)]
|
||||
//@no-rustfix
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:7:11
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:12:11
|
||||
|
|
||||
LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
|
||||
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
|
||||
@ -8,79 +8,79 @@ LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
|
||||
= help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:32:12
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:37:12
|
||||
|
|
||||
LL | fn foo6(s: &mut Vec<u32>) {
|
||||
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:45:29
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:50:29
|
||||
|
|
||||
LL | fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
|
||||
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:50:31
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:55:31
|
||||
|
|
||||
LL | fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
|
||||
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:127:16
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:132:16
|
||||
|
|
||||
LL | async fn a1(x: &mut i32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:131:16
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:136:16
|
||||
|
|
||||
LL | async fn a2(x: &mut i32, y: String) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:135:16
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:140:16
|
||||
|
|
||||
LL | async fn a3(x: &mut i32, y: String, z: String) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:139:16
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:144:16
|
||||
|
|
||||
LL | async fn a4(x: &mut i32, y: i32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:143:24
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:148:24
|
||||
|
|
||||
LL | async fn a5(x: i32, y: &mut i32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:147:24
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:152:24
|
||||
|
|
||||
LL | async fn a6(x: i32, y: &mut i32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:151:32
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:156:32
|
||||
|
|
||||
LL | async fn a7(x: i32, y: i32, z: &mut i32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:155:24
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:160:24
|
||||
|
|
||||
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:155:45
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:160:45
|
||||
|
|
||||
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:189:16
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:194:16
|
||||
|
|
||||
LL | fn cfg_warn(s: &mut u32) {}
|
||||
| ^^^^^^^^ help: consider changing to: `&u32`
|
||||
@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {}
|
||||
= note: this is cfg-gated and may require further changes
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:195:20
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:200:20
|
||||
|
|
||||
LL | fn cfg_warn(s: &mut u32) {}
|
||||
| ^^^^^^^^ help: consider changing to: `&u32`
|
||||
@ -96,19 +96,19 @@ LL | fn cfg_warn(s: &mut u32) {}
|
||||
= note: this is cfg-gated and may require further changes
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:209:39
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:214:39
|
||||
|
|
||||
LL | async fn inner_async2(x: &mut i32, y: &mut u32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&u32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:217:26
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:222:26
|
||||
|
|
||||
LL | async fn inner_async3(x: &mut i32, y: &mut u32) {
|
||||
| ^^^^^^^^ help: consider changing to: `&i32`
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:236:34
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:241:34
|
||||
|
|
||||
LL | pub async fn call_in_closure1(n: &mut str) {
|
||||
| ^^^^^^^^ help: consider changing to: `&str`
|
||||
@ -116,7 +116,7 @@ LL | pub async fn call_in_closure1(n: &mut str) {
|
||||
= warning: changing this function will impact semver compatibility
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:248:25
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:253:25
|
||||
|
|
||||
LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
|
||||
| ^^^^^^^^^^ help: consider changing to: `&usize`
|
||||
@ -124,7 +124,7 @@ LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
|
||||
= warning: changing this function will impact semver compatibility
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:255:20
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:260:20
|
||||
|
|
||||
LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
|
||||
| ^^^^^^^^^^ help: consider changing to: `&usize`
|
||||
@ -132,7 +132,7 @@ LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
|
||||
= warning: changing this function will impact semver compatibility
|
||||
|
||||
error: this argument is a mutable reference, but not used mutably
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:266:26
|
||||
--> $DIR/needless_pass_by_ref_mut.rs:271:26
|
||||
|
|
||||
LL | pub async fn closure4(n: &mut usize) {
|
||||
| ^^^^^^^^^^ help: consider changing to: `&usize`
|
||||
|
@ -22,6 +22,12 @@ fn do_vec_mut(x: &mut Vec<i64>) {
|
||||
//Nothing here
|
||||
}
|
||||
|
||||
fn do_vec_mut2(x: &mut Vec<i64>) {
|
||||
//~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w
|
||||
x.len();
|
||||
x.is_empty();
|
||||
}
|
||||
|
||||
fn do_str(x: &String) {
|
||||
//~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d
|
||||
//Nothing here either
|
||||
|
@ -13,38 +13,44 @@ error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a sl
|
||||
LL | fn do_vec_mut(x: &mut Vec<i64>) {
|
||||
| ^^^^^^^^^^^^^ help: change this to: `&mut [i64]`
|
||||
|
||||
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:25:19
|
||||
|
|
||||
LL | fn do_vec_mut2(x: &mut Vec<i64>) {
|
||||
| ^^^^^^^^^^^^^ help: change this to: `&mut [i64]`
|
||||
|
||||
error: writing `&String` instead of `&str` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:25:14
|
||||
--> $DIR/ptr_arg.rs:31:14
|
||||
|
|
||||
LL | fn do_str(x: &String) {
|
||||
| ^^^^^^^ help: change this to: `&str`
|
||||
|
||||
error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:30:18
|
||||
--> $DIR/ptr_arg.rs:36:18
|
||||
|
|
||||
LL | fn do_str_mut(x: &mut String) {
|
||||
| ^^^^^^^^^^^ help: change this to: `&mut str`
|
||||
|
||||
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:35:15
|
||||
--> $DIR/ptr_arg.rs:41:15
|
||||
|
|
||||
LL | fn do_path(x: &PathBuf) {
|
||||
| ^^^^^^^^ help: change this to: `&Path`
|
||||
|
||||
error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:40:19
|
||||
--> $DIR/ptr_arg.rs:46:19
|
||||
|
|
||||
LL | fn do_path_mut(x: &mut PathBuf) {
|
||||
| ^^^^^^^^^^^^ help: change this to: `&mut Path`
|
||||
|
||||
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:49:18
|
||||
--> $DIR/ptr_arg.rs:55:18
|
||||
|
|
||||
LL | fn do_vec(x: &Vec<i64>);
|
||||
| ^^^^^^^^^ help: change this to: `&[i64]`
|
||||
|
||||
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:63:14
|
||||
--> $DIR/ptr_arg.rs:69:14
|
||||
|
|
||||
LL | fn cloned(x: &Vec<u8>) -> Vec<u8> {
|
||||
| ^^^^^^^^
|
||||
@ -62,7 +68,7 @@ LL ~ x.to_owned()
|
||||
|
|
||||
|
||||
error: writing `&String` instead of `&str` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:73:18
|
||||
--> $DIR/ptr_arg.rs:79:18
|
||||
|
|
||||
LL | fn str_cloned(x: &String) -> String {
|
||||
| ^^^^^^^
|
||||
@ -79,7 +85,7 @@ LL ~ x.to_owned()
|
||||
|
|
||||
|
||||
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:82:19
|
||||
--> $DIR/ptr_arg.rs:88:19
|
||||
|
|
||||
LL | fn path_cloned(x: &PathBuf) -> PathBuf {
|
||||
| ^^^^^^^^
|
||||
@ -96,7 +102,7 @@ LL ~ x.to_path_buf()
|
||||
|
|
||||
|
||||
error: writing `&String` instead of `&str` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:91:44
|
||||
--> $DIR/ptr_arg.rs:97:44
|
||||
|
|
||||
LL | fn false_positive_capacity(x: &Vec<u8>, y: &String) {
|
||||
| ^^^^^^^
|
||||
@ -111,19 +117,19 @@ LL ~ let c = y;
|
||||
|
|
||||
|
||||
error: using a reference to `Cow` is not recommended
|
||||
--> $DIR/ptr_arg.rs:106:25
|
||||
--> $DIR/ptr_arg.rs:112:25
|
||||
|
|
||||
LL | fn test_cow_with_ref(c: &Cow<[i32]>) {}
|
||||
| ^^^^^^^^^^^ help: change this to: `&[i32]`
|
||||
|
||||
error: writing `&String` instead of `&str` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:136:66
|
||||
--> $DIR/ptr_arg.rs:142:66
|
||||
|
|
||||
LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
|
||||
| ^^^^^^^ help: change this to: `&str`
|
||||
|
||||
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:166:21
|
||||
--> $DIR/ptr_arg.rs:172:21
|
||||
|
|
||||
LL | fn foo_vec(vec: &Vec<u8>) {
|
||||
| ^^^^^^^^
|
||||
@ -137,7 +143,7 @@ LL ~ let _ = vec.to_owned().clone();
|
||||
|
|
||||
|
||||
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:172:23
|
||||
--> $DIR/ptr_arg.rs:178:23
|
||||
|
|
||||
LL | fn foo_path(path: &PathBuf) {
|
||||
| ^^^^^^^^
|
||||
@ -151,7 +157,7 @@ LL ~ let _ = path.to_path_buf().clone();
|
||||
|
|
||||
|
||||
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:178:21
|
||||
--> $DIR/ptr_arg.rs:184:21
|
||||
|
|
||||
LL | fn foo_str(str: &PathBuf) {
|
||||
| ^^^^^^^^
|
||||
@ -165,46 +171,46 @@ LL ~ let _ = str.to_path_buf().clone();
|
||||
|
|
||||
|
||||
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:185:29
|
||||
--> $DIR/ptr_arg.rs:191:29
|
||||
|
|
||||
LL | fn mut_vec_slice_methods(v: &mut Vec<u32>) {
|
||||
| ^^^^^^^^^^^^^ help: change this to: `&mut [u32]`
|
||||
|
||||
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:248:17
|
||||
--> $DIR/ptr_arg.rs:254:17
|
||||
|
|
||||
LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
|
||||
| ^^^^^^^^^^^^^ help: change this to: `&mut [u32]`
|
||||
|
||||
error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:248:35
|
||||
--> $DIR/ptr_arg.rs:254:35
|
||||
|
|
||||
LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
|
||||
| ^^^^^^^^^^^ help: change this to: `&mut str`
|
||||
|
||||
error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do
|
||||
--> $DIR/ptr_arg.rs:248:51
|
||||
--> $DIR/ptr_arg.rs:254:51
|
||||
|
|
||||
LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
|
||||
| ^^^^^^^^^^^^ help: change this to: `&mut Path`
|
||||
|
||||
error: using a reference to `Cow` is not recommended
|
||||
--> $DIR/ptr_arg.rs:274:39
|
||||
--> $DIR/ptr_arg.rs:280:39
|
||||
|
|
||||
LL | fn cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str {
|
||||
| ^^^^^^^^^^^^ help: change this to: `&str`
|
||||
|
||||
error: using a reference to `Cow` is not recommended
|
||||
--> $DIR/ptr_arg.rs:280:36
|
||||
--> $DIR/ptr_arg.rs:286:36
|
||||
|
|
||||
LL | fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str {
|
||||
| ^^^^^^^^^^^^^^^^ help: change this to: `&str`
|
||||
|
||||
error: using a reference to `Cow` is not recommended
|
||||
--> $DIR/ptr_arg.rs:284:40
|
||||
--> $DIR/ptr_arg.rs:290:40
|
||||
|
|
||||
LL | fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {
|
||||
| ^^^^^^^^^^^^^^^^ help: change this to: `&str`
|
||||
|
||||
error: aborting due to 23 previous errors
|
||||
error: aborting due to 24 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user