]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/tests/ui/redundant_clone.rs
New upstream version 1.66.0+dfsg1
[rustc.git] / src / tools / clippy / tests / ui / redundant_clone.rs
CommitLineData
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
6use std::ffi::OsString;
7use std::path::Path;
8
9fn 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)]
68struct Alpha;
69fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) {
70 if b { (a.clone(), a.clone()) } else { (Alpha, a) }
71}
72
73fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) {
74 (a.clone(), a)
75}
76
77struct TypeWithDrop {
78 x: String,
79}
80
81impl Drop for TypeWithDrop {
82 fn drop(&mut self) {}
83}
84
85fn 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
90fn 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
148fn 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)]
172fn 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
180fn 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
194fn 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
217fn 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
233fn 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}