• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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