]>
Commit | Line | Data |
---|---|---|
f20569fa | 1 | #![warn(clippy::needless_pass_by_value)] |
2b03887a | 2 | #![allow(dead_code)] |
f20569fa | 3 | #![allow( |
f20569fa | 4 | clippy::option_option, |
2b03887a FG |
5 | clippy::redundant_clone, |
6 | clippy::redundant_pattern_matching, | |
7 | clippy::single_match, | |
8 | clippy::uninlined_format_args | |
f20569fa XL |
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 | } |