]> git.lizzy.rs Git - rust.git/blob - tests/ui/needless_pass_by_value.rs
Auto merge of #8359 - flip1995:rustup, r=flip1995
[rust.git] / tests / ui / needless_pass_by_value.rs
1 #![warn(clippy::needless_pass_by_value)]
2 #![allow(
3     dead_code,
4     clippy::single_match,
5     clippy::redundant_pattern_matching,
6     clippy::option_option,
7     clippy::redundant_clone
8 )]
9
10 use std::borrow::Borrow;
11 use std::collections::HashSet;
12 use std::convert::AsRef;
13 use std::mem::MaybeUninit;
14
15 // `v` should be warned
16 // `w`, `x` and `y` are allowed (moved or mutated)
17 fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
18     assert_eq!(v.len(), 42);
19
20     consume(w);
21
22     x.push(T::default());
23
24     y
25 }
26
27 fn consume<T>(_: T) {}
28
29 struct Wrapper(String);
30
31 fn bar(x: String, y: Wrapper) {
32     assert_eq!(x.len(), 42);
33     assert_eq!(y.0.len(), 42);
34 }
35
36 // V implements `Borrow<V>`, but should be warned correctly
37 fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
38     println!("{}", t.borrow());
39     println!("{}", u.as_ref());
40     consume(&v);
41 }
42
43 // ok
44 fn test_fn<F: Fn(i32) -> i32>(f: F) {
45     f(1);
46 }
47
48 // x should be warned, but y is ok
49 fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
50     match x {
51         Some(Some(_)) => 1, // not moved
52         _ => 0,
53     };
54
55     match y {
56         Some(Some(s)) => consume(s), // moved
57         _ => (),
58     };
59 }
60
61 // x and y should be warned, but z is ok
62 fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
63     let Wrapper(s) = z; // moved
64     let Wrapper(ref t) = y; // not moved
65     let Wrapper(_) = y; // still not moved
66
67     assert_eq!(x.0.len(), s.len());
68     println!("{}", t);
69 }
70
71 trait Foo {}
72
73 // `S: Serialize` is allowed to be passed by value, since a caller can pass `&S` instead
74 trait Serialize {}
75 impl<'a, T> Serialize for &'a T where T: Serialize {}
76 impl Serialize for i32 {}
77
78 fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
79
80 fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
81     s.capacity();
82     let _ = t.clone();
83     u.capacity();
84     let _ = v.clone();
85 }
86
87 struct S<T, U>(T, U);
88
89 impl<T: Serialize, U> S<T, U> {
90     fn foo(
91         self,
92         // taking `self` by value is always allowed
93         s: String,
94         t: String,
95     ) -> usize {
96         s.len() + t.capacity()
97     }
98
99     fn bar(_t: T, // Ok, since `&T: Serialize` too
100     ) {
101     }
102
103     fn baz(&self, _u: U, _s: Self) {}
104 }
105
106 trait FalsePositive {
107     fn visit_str(s: &str);
108     fn visit_string(s: String) {
109         Self::visit_str(&s);
110     }
111 }
112
113 // shouldn't warn on extern funcs
114 extern "C" fn ext(x: MaybeUninit<usize>) -> usize {
115     unsafe { x.assume_init() }
116 }
117
118 // exempt RangeArgument
119 fn range<T: ::std::ops::RangeBounds<usize>>(range: T) {
120     let _ = range.start_bound();
121 }
122
123 struct CopyWrapper(u32);
124
125 fn bar_copy(x: u32, y: CopyWrapper) {
126     assert_eq!(x, 42);
127     assert_eq!(y.0, 42);
128 }
129
130 // x and y should be warned, but z is ok
131 fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
132     let CopyWrapper(s) = z; // moved
133     let CopyWrapper(ref t) = y; // not moved
134     let CopyWrapper(_) = y; // still not moved
135
136     assert_eq!(x.0, s);
137     println!("{}", t);
138 }
139
140 // The following 3 lines should not cause an ICE. See #2831
141 trait Bar<'a, A> {}
142 impl<'b, T> Bar<'b, T> for T {}
143 fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {}
144
145 // Also this should not cause an ICE. See #2831
146 trait Club<'a, A> {}
147 impl<T> Club<'static, T> for T {}
148 fn more_fun(_item: impl Club<'static, i32>) {}
149
150 fn is_sync<T>(_: T)
151 where
152     T: Sync,
153 {
154 }
155
156 fn main() {
157     // This should not cause an ICE either
158     // https://github.com/rust-lang/rust-clippy/issues/3144
159     is_sync(HashSet::<usize>::new());
160 }