1 #![feature(lint_reasons)]
2 #![allow(
3 unused,
4 clippy::many_single_char_names,
5 clippy::needless_lifetimes,
6 clippy::redundant_clone
7 )]
8 #![warn(clippy::ptr_arg)]
9
10 use std::borrow::Cow;
11 use std::path::{Path, PathBuf};
12
do_vec(x: &Vec<i64>)13 fn do_vec(x: &Vec<i64>) {
14 //Nothing here
15 }
16
do_vec_mut(x: &mut Vec<i64>)17 fn do_vec_mut(x: &mut Vec<i64>) {
18 //Nothing here
19 }
20
do_str(x: &String)21 fn do_str(x: &String) {
22 //Nothing here either
23 }
24
do_str_mut(x: &mut String)25 fn do_str_mut(x: &mut String) {
26 //Nothing here either
27 }
28
do_path(x: &PathBuf)29 fn do_path(x: &PathBuf) {
30 //Nothing here either
31 }
32
do_path_mut(x: &mut PathBuf)33 fn do_path_mut(x: &mut PathBuf) {
34 //Nothing here either
35 }
36
main()37 fn main() {}
38
39 trait Foo {
40 type Item;
do_vec(x: &Vec<i64>)41 fn do_vec(x: &Vec<i64>);
do_item(x: &Self::Item)42 fn do_item(x: &Self::Item);
43 }
44
45 struct Bar;
46
47 // no error, in trait impl (#425)
48 impl Foo for Bar {
49 type Item = Vec<u8>;
do_vec(x: &Vec<i64>)50 fn do_vec(x: &Vec<i64>) {}
do_item(x: &Vec<u8>)51 fn do_item(x: &Vec<u8>) {}
52 }
53
cloned(x: &Vec<u8>) -> Vec<u8>54 fn cloned(x: &Vec<u8>) -> Vec<u8> {
55 let e = x.clone();
56 let f = e.clone(); // OK
57 let g = x;
58 let h = g.clone();
59 let i = (e).clone();
60 x.clone()
61 }
62
str_cloned(x: &String) -> String63 fn str_cloned(x: &String) -> String {
64 let a = x.clone();
65 let b = x.clone();
66 let c = b.clone();
67 let d = a.clone().clone().clone();
68 x.clone()
69 }
70
path_cloned(x: &PathBuf) -> PathBuf71 fn path_cloned(x: &PathBuf) -> PathBuf {
72 let a = x.clone();
73 let b = x.clone();
74 let c = b.clone();
75 let d = a.clone().clone().clone();
76 x.clone()
77 }
78
false_positive_capacity(x: &Vec<u8>, y: &String)79 fn false_positive_capacity(x: &Vec<u8>, y: &String) {
80 let a = x.capacity();
81 let b = y.clone();
82 let c = y.as_str();
83 }
84
false_positive_capacity_too(x: &String) -> String85 fn false_positive_capacity_too(x: &String) -> String {
86 if x.capacity() > 1024 {
87 panic!("Too large!");
88 }
89 x.clone()
90 }
91
92 #[allow(dead_code)]
test_cow_with_ref(c: &Cow<[i32]>)93 fn test_cow_with_ref(c: &Cow<[i32]>) {}
94
test_cow(c: Cow<[i32]>)95 fn test_cow(c: Cow<[i32]>) {
96 let _c = c;
97 }
98
99 trait Foo2 {
do_string(&self)100 fn do_string(&self);
101 }
102
103 // no error for &self references where self is of type String (#2293)
104 impl Foo2 for String {
do_string(&self)105 fn do_string(&self) {}
106 }
107
108 // Check that the allow attribute on parameters is honored
109 mod issue_5644 {
110 use std::borrow::Cow;
111 use std::path::PathBuf;
112
allowed( #[allow(clippy::ptr_arg)] _v: &Vec<u32>, #[allow(clippy::ptr_arg)] _s: &String, #[allow(clippy::ptr_arg)] _p: &PathBuf, #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>, #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>, )113 fn allowed(
114 #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
115 #[allow(clippy::ptr_arg)] _s: &String,
116 #[allow(clippy::ptr_arg)] _p: &PathBuf,
117 #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
118 #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
119 ) {
120 }
121
some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String)122 fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
123
124 struct S;
125 impl S {
allowed( #[allow(clippy::ptr_arg)] _v: &Vec<u32>, #[allow(clippy::ptr_arg)] _s: &String, #[allow(clippy::ptr_arg)] _p: &PathBuf, #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>, #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>, )126 fn allowed(
127 #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
128 #[allow(clippy::ptr_arg)] _s: &String,
129 #[allow(clippy::ptr_arg)] _p: &PathBuf,
130 #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
131 #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
132 ) {
133 }
134 }
135
136 trait T {
allowed( #[allow(clippy::ptr_arg)] _v: &Vec<u32>, #[allow(clippy::ptr_arg)] _s: &String, #[allow(clippy::ptr_arg)] _p: &PathBuf, #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>, #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>, )137 fn allowed(
138 #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
139 #[allow(clippy::ptr_arg)] _s: &String,
140 #[allow(clippy::ptr_arg)] _p: &PathBuf,
141 #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
142 #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
143 ) {
144 }
145 }
146 }
147
148 mod issue6509 {
149 use std::path::PathBuf;
150
foo_vec(vec: &Vec<u8>)151 fn foo_vec(vec: &Vec<u8>) {
152 let _ = vec.clone().pop();
153 let _ = vec.clone().clone();
154 }
155
foo_path(path: &PathBuf)156 fn foo_path(path: &PathBuf) {
157 let _ = path.clone().pop();
158 let _ = path.clone().clone();
159 }
160
foo_str(str: &PathBuf)161 fn foo_str(str: &PathBuf) {
162 let _ = str.clone().pop();
163 let _ = str.clone().clone();
164 }
165 }
166
mut_vec_slice_methods(v: &mut Vec<u32>)167 fn mut_vec_slice_methods(v: &mut Vec<u32>) {
168 v.copy_within(1..5, 10);
169 }
170
mut_vec_vec_methods(v: &mut Vec<u32>)171 fn mut_vec_vec_methods(v: &mut Vec<u32>) {
172 v.clear();
173 }
174
vec_contains(v: &Vec<u32>) -> bool175 fn vec_contains(v: &Vec<u32>) -> bool {
176 [vec![], vec![0]].as_slice().contains(v)
177 }
178
fn_requires_vec(v: &Vec<u32>) -> bool179 fn fn_requires_vec(v: &Vec<u32>) -> bool {
180 vec_contains(v)
181 }
182
impl_fn_requires_vec(v: &Vec<u32>, f: impl Fn(&Vec<u32>))183 fn impl_fn_requires_vec(v: &Vec<u32>, f: impl Fn(&Vec<u32>)) {
184 f(v);
185 }
186
dyn_fn_requires_vec(v: &Vec<u32>, f: &dyn Fn(&Vec<u32>))187 fn dyn_fn_requires_vec(v: &Vec<u32>, f: &dyn Fn(&Vec<u32>)) {
188 f(v);
189 }
190
191 // No error for types behind an alias (#7699)
192 type A = Vec<u8>;
aliased(a: &A)193 fn aliased(a: &A) {}
194
195 // Issue #8366
196 pub trait Trait {
f(v: &mut Vec<i32>)197 fn f(v: &mut Vec<i32>);
f2(v: &mut Vec<i32>)198 fn f2(v: &mut Vec<i32>) {}
199 }
200
201 // Issue #8463
two_vecs(a: &mut Vec<u32>, b: &mut Vec<u32>)202 fn two_vecs(a: &mut Vec<u32>, b: &mut Vec<u32>) {
203 a.push(0);
204 a.push(0);
205 a.push(0);
206 b.push(1);
207 }
208
209 // Issue #8495
cow_conditional_to_mut(a: &mut Cow<str>)210 fn cow_conditional_to_mut(a: &mut Cow<str>) {
211 if a.is_empty() {
212 a.to_mut().push_str("foo");
213 }
214 }
215
216 // Issue #9542
dyn_trait_ok(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf)217 fn dyn_trait_ok(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
218 trait T {}
219 impl<U> T for Vec<U> {}
220 impl T for String {}
221 impl T for PathBuf {}
222 fn takes_dyn(_: &mut dyn T) {}
223
224 takes_dyn(a);
225 takes_dyn(b);
226 takes_dyn(c);
227 }
228
dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf)229 fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
230 trait T {}
231 impl<U> T for Vec<U> {}
232 impl<U> T for [U] {}
233 impl T for String {}
234 impl T for str {}
235 impl T for PathBuf {}
236 impl T for Path {}
237 fn takes_dyn(_: &mut dyn T) {}
238
239 takes_dyn(a);
240 takes_dyn(b);
241 takes_dyn(c);
242 }
243
244 mod issue_9218 {
245 use std::borrow::Cow;
246
cow_non_elided_lifetime<'a>(input: &Cow<'a, str>) -> &'a str247 fn cow_non_elided_lifetime<'a>(input: &Cow<'a, str>) -> &'a str {
248 todo!()
249 }
250
251 // This one has an anonymous lifetime so it's not okay
cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str252 fn cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str {
253 todo!()
254 }
255
256 // These two's return types don't use use 'a so it's not okay
cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str257 fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str {
258 todo!()
259 }
cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str260 fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {
261 todo!()
262 }
263
264 // Inferred to be `&'a str`, afaik.
cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str265 fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
266 todo!()
267 }
268 }
269