]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | // run-rustfix |
2 | // rustfix-only-machine-applicable | |
064997fb | 3 | #![feature(lint_reasons)] |
2b03887a FG |
4 | #![allow(clippy::drop_non_drop, clippy::implicit_clone, clippy::uninlined_format_args)] |
5 | ||
f20569fa XL |
6 | use std::ffi::OsString; |
7 | use std::path::Path; | |
8 | ||
9 | fn main() { | |
10 | let _s = ["lorem", "ipsum"].join(" ").to_string(); | |
11 | ||
12 | let s = String::from("foo"); | |
13 | let _s = s.clone(); | |
14 | ||
15 | let s = String::from("foo"); | |
16 | let _s = s.to_string(); | |
17 | ||
18 | let s = String::from("foo"); | |
19 | let _s = s.to_owned(); | |
20 | ||
21 | let _s = Path::new("/a/b/").join("c").to_owned(); | |
22 | ||
23 | let _s = Path::new("/a/b/").join("c").to_path_buf(); | |
24 | ||
25 | let _s = OsString::new().to_owned(); | |
26 | ||
27 | let _s = OsString::new().to_os_string(); | |
28 | ||
29 | // Check that lint level works | |
30 | #[allow(clippy::redundant_clone)] | |
31 | let _s = String::new().to_string(); | |
32 | ||
064997fb FG |
33 | // Check that lint level works |
34 | #[expect(clippy::redundant_clone)] | |
35 | let _s = String::new().to_string(); | |
36 | ||
f20569fa XL |
37 | let tup = (String::from("foo"),); |
38 | let _t = tup.0.clone(); | |
39 | ||
40 | let tup_ref = &(String::from("foo"),); | |
41 | let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed | |
42 | ||
43 | { | |
44 | let x = String::new(); | |
45 | let y = &x; | |
46 | ||
47 | let _x = x.clone(); // ok; `x` is borrowed by `y` | |
48 | ||
49 | let _ = y.len(); | |
50 | } | |
51 | ||
52 | let x = (String::new(),); | |
53 | let _ = Some(String::new()).unwrap_or_else(|| x.0.clone()); // ok; closure borrows `x` | |
54 | ||
55 | with_branch(Alpha, true); | |
56 | cannot_double_move(Alpha); | |
57 | cannot_move_from_type_with_drop(); | |
58 | borrower_propagation(); | |
59 | not_consumed(); | |
60 | issue_5405(); | |
61 | manually_drop(); | |
cdc7bbd5 | 62 | clone_then_move_cloned(); |
136023e0 XL |
63 | hashmap_neg(); |
64 | false_negative_5707(); | |
f20569fa XL |
65 | } |
66 | ||
67 | #[derive(Clone)] | |
68 | struct Alpha; | |
69 | fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) { | |
70 | if b { (a.clone(), a.clone()) } else { (Alpha, a) } | |
71 | } | |
72 | ||
73 | fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) { | |
74 | (a.clone(), a) | |
75 | } | |
76 | ||
77 | struct TypeWithDrop { | |
78 | x: String, | |
79 | } | |
80 | ||
81 | impl Drop for TypeWithDrop { | |
82 | fn drop(&mut self) {} | |
83 | } | |
84 | ||
85 | fn cannot_move_from_type_with_drop() -> String { | |
86 | let s = TypeWithDrop { x: String::new() }; | |
87 | s.x.clone() // removing this `clone()` summons E0509 | |
88 | } | |
89 | ||
90 | fn borrower_propagation() { | |
91 | let s = String::new(); | |
92 | let t = String::new(); | |
93 | ||
94 | { | |
95 | fn b() -> bool { | |
96 | unimplemented!() | |
97 | } | |
98 | let _u = if b() { &s } else { &t }; | |
99 | ||
100 | // ok; `s` and `t` are possibly borrowed | |
101 | let _s = s.clone(); | |
102 | let _t = t.clone(); | |
103 | } | |
104 | ||
105 | { | |
106 | let _u = || s.len(); | |
107 | let _v = [&t; 32]; | |
108 | let _s = s.clone(); // ok | |
109 | let _t = t.clone(); // ok | |
110 | } | |
111 | ||
112 | { | |
113 | let _u = { | |
114 | let u = Some(&s); | |
115 | let _ = s.clone(); // ok | |
116 | u | |
117 | }; | |
118 | let _s = s.clone(); // ok | |
119 | } | |
120 | ||
121 | { | |
122 | use std::convert::identity as id; | |
123 | let _u = id(id(&s)); | |
124 | let _s = s.clone(); // ok, `u` borrows `s` | |
125 | } | |
126 | ||
127 | let _s = s.clone(); | |
128 | let _t = t.clone(); | |
129 | ||
130 | #[derive(Clone)] | |
131 | struct Foo { | |
132 | x: usize, | |
133 | } | |
134 | ||
135 | { | |
136 | let f = Foo { x: 123 }; | |
137 | let _x = Some(f.x); | |
138 | let _f = f.clone(); | |
139 | } | |
140 | ||
141 | { | |
142 | let f = Foo { x: 123 }; | |
143 | let _x = &f.x; | |
144 | let _f = f.clone(); // ok | |
145 | } | |
146 | } | |
147 | ||
148 | fn not_consumed() { | |
149 | let x = std::path::PathBuf::from("home"); | |
150 | let y = x.clone().join("matthias"); | |
151 | // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is | |
152 | // redundant. (It also does not consume the PathBuf) | |
153 | ||
154 | println!("x: {:?}, y: {:?}", x, y); | |
155 | ||
156 | let mut s = String::new(); | |
157 | s.clone().push_str("foo"); // OK, removing this `clone()` will change the behavior. | |
158 | s.push_str("bar"); | |
159 | assert_eq!(s, "bar"); | |
160 | ||
161 | let t = Some(s); | |
162 | // OK | |
163 | if let Some(x) = t.clone() { | |
164 | println!("{}", x); | |
165 | } | |
166 | if let Some(x) = t { | |
167 | println!("{}", x); | |
168 | } | |
169 | } | |
170 | ||
171 | #[allow(clippy::clone_on_copy)] | |
172 | fn issue_5405() { | |
173 | let a: [String; 1] = [String::from("foo")]; | |
174 | let _b: String = a[0].clone(); | |
175 | ||
176 | let c: [usize; 2] = [2, 3]; | |
177 | let _d: usize = c[1].clone(); | |
178 | } | |
179 | ||
180 | fn manually_drop() { | |
181 | use std::mem::ManuallyDrop; | |
182 | use std::sync::Arc; | |
183 | ||
184 | let a = ManuallyDrop::new(Arc::new("Hello!".to_owned())); | |
185 | let _ = a.clone(); // OK | |
186 | ||
187 | let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a)); | |
188 | unsafe { | |
189 | Arc::from_raw(p); | |
190 | Arc::from_raw(p); | |
191 | } | |
192 | } | |
cdc7bbd5 XL |
193 | |
194 | fn clone_then_move_cloned() { | |
195 | // issue #5973 | |
196 | let x = Some(String::new()); | |
197 | // ok, x is moved while the clone is in use. | |
198 | assert_eq!(x.clone(), None, "not equal {}", x.unwrap()); | |
199 | ||
200 | // issue #5595 | |
201 | fn foo<F: Fn()>(_: &Alpha, _: F) {} | |
202 | let x = Alpha; | |
203 | // ok, data is moved while the clone is in use. | |
204 | foo(&x.clone(), move || { | |
205 | let _ = x; | |
206 | }); | |
207 | ||
208 | // issue #6998 | |
209 | struct S(String); | |
210 | impl S { | |
211 | fn m(&mut self) {} | |
212 | } | |
213 | let mut x = S(String::new()); | |
214 | x.0.clone().chars().for_each(|_| x.m()); | |
215 | } | |
136023e0 XL |
216 | |
217 | fn hashmap_neg() { | |
218 | // issue 5707 | |
219 | use std::collections::HashMap; | |
220 | use std::path::PathBuf; | |
221 | ||
222 | let p = PathBuf::from("/"); | |
223 | ||
224 | let mut h: HashMap<&str, &str> = HashMap::new(); | |
225 | h.insert("orig-p", p.to_str().unwrap()); | |
226 | ||
227 | let mut q = p.clone(); | |
228 | q.push("foo"); | |
229 | ||
230 | println!("{:?} {}", h, q.display()); | |
231 | } | |
232 | ||
233 | fn false_negative_5707() { | |
234 | fn foo(_x: &Alpha, _y: &mut Alpha) {} | |
235 | ||
236 | let x = Alpha; | |
237 | let mut y = Alpha; | |
238 | foo(&x, &mut y); | |
239 | let _z = x.clone(); // pr 7346 can't lint on `x` | |
240 | drop(y); | |
241 | } |