]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/needless_borrow.fixed
Merge commit 'f4850f7292efa33759b4f7f9b7621268979e9914' into clippyup
[rust.git] / src / tools / clippy / tests / ui / needless_borrow.fixed
1 // run-rustfix
2 #![feature(custom_inner_attributes, lint_reasons)]
3
4 #[warn(clippy::all, clippy::needless_borrow)]
5 #[allow(unused_variables)]
6 #[allow(
7     clippy::uninlined_format_args,
8     clippy::unnecessary_mut_passed,
9     clippy::unnecessary_to_owned
10 )]
11 fn main() {
12     let a = 5;
13     let ref_a = &a;
14     let _ = x(&a); // no warning
15     let _ = x(&a); // warn
16
17     let mut b = 5;
18     mut_ref(&mut b); // no warning
19     mut_ref(&mut b); // warn
20
21     let s = &String::from("hi");
22     let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not
23     let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`
24     let vec = Vec::new();
25     let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`
26     h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait`
27     let garbl = match 42 {
28         44 => &a,
29         45 => {
30             println!("foo");
31             &a
32         },
33         46 => &a,
34         47 => {
35             println!("foo");
36             loop {
37                 println!("{}", a);
38                 if a == 25 {
39                     break ref_a;
40                 }
41             }
42         },
43         _ => panic!(),
44     };
45
46     let _ = x(&a);
47     let _ = x(&a);
48     let _ = x(&mut b);
49     let _ = x(ref_a);
50     {
51         let b = &mut b;
52         x(b);
53     }
54
55     // Issue #8191
56     let mut x = 5;
57     let mut x = &mut x;
58
59     mut_ref(x);
60     mut_ref(x);
61     let y: &mut i32 = x;
62     let y: &mut i32 = x;
63
64     let y = match 0 {
65         // Don't lint. Removing the borrow would move 'x'
66         0 => &mut x,
67         _ => &mut *x,
68     };
69     let y: &mut i32 = match 0 {
70         // Lint here. The type given above triggers auto-borrow.
71         0 => x,
72         _ => &mut *x,
73     };
74     fn ref_mut_i32(_: &mut i32) {}
75     ref_mut_i32(match 0 {
76         // Lint here. The type given above triggers auto-borrow.
77         0 => x,
78         _ => &mut *x,
79     });
80     // use 'x' after to make sure it's still usable in the fixed code.
81     *x = 5;
82
83     let s = String::new();
84     // let _ = (&s).len();
85     // let _ = (&s).capacity();
86     // let _ = (&&s).capacity();
87
88     let x = (1, 2);
89     let _ = x.0;
90     let x = &x as *const (i32, i32);
91     let _ = unsafe { (*x).0 };
92
93     // Issue #8367
94     trait Foo {
95         fn foo(self);
96     }
97     impl Foo for &'_ () {
98         fn foo(self) {}
99     }
100     (&()).foo(); // Don't lint. `()` doesn't implement `Foo`
101     (&()).foo();
102
103     impl Foo for i32 {
104         fn foo(self) {}
105     }
106     impl Foo for &'_ i32 {
107         fn foo(self) {}
108     }
109     (&5).foo(); // Don't lint. `5` will call `<i32 as Foo>::foo`
110     (&5).foo();
111
112     trait FooRef {
113         fn foo_ref(&self);
114     }
115     impl FooRef for () {
116         fn foo_ref(&self) {}
117     }
118     impl FooRef for &'_ () {
119         fn foo_ref(&self) {}
120     }
121     (&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`
122
123     struct S;
124     impl From<S> for u32 {
125         fn from(s: S) -> Self {
126             (&s).into()
127         }
128     }
129     impl From<&S> for u32 {
130         fn from(s: &S) -> Self {
131             0
132         }
133     }
134
135     let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
136     let _ = std::path::Path::new(".").join(".");
137     deref_target_is_x(X);
138     multiple_constraints([[""]]);
139     multiple_constraints_normalizes_to_same(X, X);
140     let _ = Some("").unwrap_or("");
141     let _ = std::fs::write("x", "".to_string());
142
143     only_sized(&""); // Don't lint. `Sized` is only bound
144     let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
145     let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
146     ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
147     refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
148     multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
149 }
150
151 #[allow(clippy::needless_borrowed_reference)]
152 fn x(y: &i32) -> i32 {
153     *y
154 }
155
156 fn mut_ref(y: &mut i32) {
157     *y = 5;
158 }
159
160 fn f<T: Copy>(y: &T) -> T {
161     *y
162 }
163
164 fn g(y: &[u8]) -> u8 {
165     y[0]
166 }
167
168 trait Trait {}
169
170 impl<'a> Trait for &'a str {}
171
172 fn h(_: &dyn Trait) {}
173
174 #[allow(dead_code)]
175 fn check_expect_suppression() {
176     let a = 5;
177     #[expect(clippy::needless_borrow)]
178     let _ = x(&&a);
179 }
180
181 #[allow(dead_code)]
182 mod issue9160 {
183     pub struct S<F> {
184         f: F,
185     }
186
187     impl<T, F> S<F>
188     where
189         F: Fn() -> T,
190     {
191         fn calls_field(&self) -> T {
192             (self.f)()
193         }
194     }
195
196     impl<T, F> S<F>
197     where
198         F: FnMut() -> T,
199     {
200         fn calls_mut_field(&mut self) -> T {
201             (self.f)()
202         }
203     }
204 }
205
206 #[derive(Clone, Copy)]
207 struct X;
208
209 impl std::ops::Deref for X {
210     type Target = X;
211     fn deref(&self) -> &Self::Target {
212         self
213     }
214 }
215
216 fn deref_target_is_x<T>(_: T)
217 where
218     T: std::ops::Deref<Target = X>,
219 {
220 }
221
222 fn multiple_constraints<T, U, V, X, Y>(_: T)
223 where
224     T: IntoIterator<Item = U> + IntoIterator<Item = X>,
225     U: IntoIterator<Item = V>,
226     V: AsRef<str>,
227     X: IntoIterator<Item = Y>,
228     Y: AsRef<std::ffi::OsStr>,
229 {
230 }
231
232 fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
233 where
234     T: std::ops::Deref<Target = U>,
235     U: std::ops::Deref<Target = V>,
236 {
237 }
238
239 fn only_sized<T>(_: T) {}
240
241 fn ref_as_ref_path<T: 'static>(_: &'static T)
242 where
243     &'static T: AsRef<std::path::Path>,
244 {
245 }
246
247 trait RefsOnly {
248     type Referent;
249 }
250
251 impl<T> RefsOnly for &T {
252     type Referent = T;
253 }
254
255 fn refs_only<T, U>(_: T)
256 where
257     T: RefsOnly<Referent = U>,
258 {
259 }
260
261 fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
262 where
263     T: IntoIterator<Item = U>,
264     U: IntoIterator<Item = V>,
265     V: AsRef<str>,
266 {
267 }
268
269 // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
270 #[allow(dead_code)]
271 mod copyable_iterator {
272     #[derive(Clone, Copy)]
273     struct Iter;
274     impl Iterator for Iter {
275         type Item = ();
276         fn next(&mut self) -> Option<Self::Item> {
277             None
278         }
279     }
280     fn takes_iter(_: impl Iterator) {}
281     fn dont_warn(mut x: Iter) {
282         takes_iter(&mut x);
283     }
284     #[allow(unused_mut)]
285     fn warn(mut x: &mut Iter) {
286         takes_iter(x)
287     }
288 }
289
290 mod under_msrv {
291     #![allow(dead_code)]
292     #![clippy::msrv = "1.52.0"]
293
294     fn foo() {
295         let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
296     }
297 }
298
299 mod meets_msrv {
300     #![allow(dead_code)]
301     #![clippy::msrv = "1.53.0"]
302
303     fn foo() {
304         let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
305     }
306 }
307
308 #[allow(unused)]
309 fn issue9383() {
310     // Should not lint because unions need explicit deref when accessing field
311     use std::mem::ManuallyDrop;
312
313     union Coral {
314         crab: ManuallyDrop<Vec<i32>>,
315     }
316
317     union Ocean {
318         coral: ManuallyDrop<Coral>,
319     }
320
321     let mut ocean = Ocean {
322         coral: ManuallyDrop::new(Coral {
323             crab: ManuallyDrop::new(vec![1, 2, 3]),
324         }),
325     };
326
327     unsafe {
328         ManuallyDrop::drop(&mut (&mut ocean.coral).crab);
329
330         (*ocean.coral).crab = ManuallyDrop::new(vec![4, 5, 6]);
331         ManuallyDrop::drop(&mut (*ocean.coral).crab);
332
333         ManuallyDrop::drop(&mut ocean.coral);
334     }
335 }
336
337 #[allow(dead_code)]
338 fn closure_test() {
339     let env = "env".to_owned();
340     let arg = "arg".to_owned();
341     let f = |arg| {
342         let loc = "loc".to_owned();
343         let _ = std::fs::write("x", &env); // Don't lint. In environment
344         let _ = std::fs::write("x", arg);
345         let _ = std::fs::write("x", loc);
346     };
347     let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
348     f(arg);
349 }
350
351 #[allow(dead_code)]
352 mod significant_drop {
353     #[derive(Debug)]
354     struct X;
355
356     #[derive(Debug)]
357     struct Y;
358
359     impl Drop for Y {
360         fn drop(&mut self) {}
361     }
362
363     fn foo(x: X, y: Y) {
364         debug(x);
365         debug(&y); // Don't lint. Has significant drop
366     }
367
368     fn debug(_: impl std::fmt::Debug) {}
369 }
370
371 #[allow(dead_code)]
372 mod used_exactly_once {
373     fn foo(x: String) {
374         use_x(x);
375     }
376     fn use_x(_: impl AsRef<str>) {}
377 }
378
379 #[allow(dead_code)]
380 mod used_more_than_once {
381     fn foo(x: String) {
382         use_x(&x);
383         use_x_again(&x);
384     }
385     fn use_x(_: impl AsRef<str>) {}
386     fn use_x_again(_: impl AsRef<str>) {}
387 }
388
389 // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
390 #[allow(dead_code)]
391 mod issue_9111 {
392     struct A;
393
394     impl Extend<u8> for A {
395         fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
396             unimplemented!()
397         }
398     }
399
400     impl<'a> Extend<&'a u8> for A {
401         fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
402             unimplemented!()
403         }
404     }
405
406     fn main() {
407         let mut a = A;
408         a.extend(&[]); // vs a.extend([]);
409     }
410 }
411
412 #[allow(dead_code)]
413 mod issue_9710 {
414     fn main() {
415         let string = String::new();
416         for _i in 0..10 {
417             f(&string);
418         }
419     }
420
421     fn f<T: AsRef<str>>(_: T) {}
422 }
423
424 #[allow(dead_code)]
425 mod issue_9739 {
426     fn foo<D: std::fmt::Display>(_it: impl IntoIterator<Item = D>) {}
427
428     fn main() {
429         foo(if std::env::var_os("HI").is_some() {
430             &[0]
431         } else {
432             &[] as &[u32]
433         });
434     }
435 }
436
437 #[allow(dead_code)]
438 mod issue_9739_method_variant {
439     struct S;
440
441     impl S {
442         fn foo<D: std::fmt::Display>(&self, _it: impl IntoIterator<Item = D>) {}
443     }
444
445     fn main() {
446         S.foo(if std::env::var_os("HI").is_some() {
447             &[0]
448         } else {
449             &[] as &[u32]
450         });
451     }
452 }
453
454 #[allow(dead_code)]
455 mod issue_9782 {
456     fn foo<T: AsRef<[u8]>>(t: T) {
457         println!("{}", std::mem::size_of::<T>());
458         let _t: &[u8] = t.as_ref();
459     }
460
461     fn main() {
462         let a: [u8; 100] = [0u8; 100];
463
464         // 100
465         foo::<[u8; 100]>(a);
466         foo(a);
467
468         // 16
469         foo::<&[u8]>(&a);
470         foo(a.as_slice());
471
472         // 8
473         foo::<&[u8; 100]>(&a);
474         foo(a);
475     }
476 }
477
478 #[allow(dead_code)]
479 mod issue_9782_type_relative_variant {
480     struct S;
481
482     impl S {
483         fn foo<T: AsRef<[u8]>>(t: T) {
484             println!("{}", std::mem::size_of::<T>());
485             let _t: &[u8] = t.as_ref();
486         }
487     }
488
489     fn main() {
490         let a: [u8; 100] = [0u8; 100];
491
492         S::foo::<&[u8; 100]>(&a);
493     }
494 }
495
496 #[allow(dead_code)]
497 mod issue_9782_method_variant {
498     struct S;
499
500     impl S {
501         fn foo<T: AsRef<[u8]>>(&self, t: T) {
502             println!("{}", std::mem::size_of::<T>());
503             let _t: &[u8] = t.as_ref();
504         }
505     }
506
507     fn main() {
508         let a: [u8; 100] = [0u8; 100];
509
510         S.foo::<&[u8; 100]>(&a);
511     }
512 }