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