]> git.lizzy.rs Git - rust.git/blob - tests/ui/redundant_clone.rs
Add version = "Two" to rustfmt.toml
[rust.git] / tests / ui / redundant_clone.rs
1 // run-rustfix
2 // rustfix-only-machine-applicable
3
4 #![allow(clippy::implicit_clone)]
5 use std::ffi::OsString;
6 use std::path::Path;
7
8 fn main() {
9     let _s = ["lorem", "ipsum"].join(" ").to_string();
10
11     let s = String::from("foo");
12     let _s = s.clone();
13
14     let s = String::from("foo");
15     let _s = s.to_string();
16
17     let s = String::from("foo");
18     let _s = s.to_owned();
19
20     let _s = Path::new("/a/b/").join("c").to_owned();
21
22     let _s = Path::new("/a/b/").join("c").to_path_buf();
23
24     let _s = OsString::new().to_owned();
25
26     let _s = OsString::new().to_os_string();
27
28     // Check that lint level works
29     #[allow(clippy::redundant_clone)]
30     let _s = String::new().to_string();
31
32     let tup = (String::from("foo"),);
33     let _t = tup.0.clone();
34
35     let tup_ref = &(String::from("foo"),);
36     let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed
37
38     {
39         let x = String::new();
40         let y = &x;
41
42         let _x = x.clone(); // ok; `x` is borrowed by `y`
43
44         let _ = y.len();
45     }
46
47     let x = (String::new(),);
48     let _ = Some(String::new()).unwrap_or_else(|| x.0.clone()); // ok; closure borrows `x`
49
50     with_branch(Alpha, true);
51     cannot_double_move(Alpha);
52     cannot_move_from_type_with_drop();
53     borrower_propagation();
54     not_consumed();
55     issue_5405();
56     manually_drop();
57 }
58
59 #[derive(Clone)]
60 struct Alpha;
61 fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) {
62     if b { (a.clone(), a.clone()) } else { (Alpha, a) }
63 }
64
65 fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) {
66     (a.clone(), a)
67 }
68
69 struct TypeWithDrop {
70     x: String,
71 }
72
73 impl Drop for TypeWithDrop {
74     fn drop(&mut self) {}
75 }
76
77 fn cannot_move_from_type_with_drop() -> String {
78     let s = TypeWithDrop { x: String::new() };
79     s.x.clone() // removing this `clone()` summons E0509
80 }
81
82 fn borrower_propagation() {
83     let s = String::new();
84     let t = String::new();
85
86     {
87         fn b() -> bool {
88             unimplemented!()
89         }
90         let _u = if b() { &s } else { &t };
91
92         // ok; `s` and `t` are possibly borrowed
93         let _s = s.clone();
94         let _t = t.clone();
95     }
96
97     {
98         let _u = || s.len();
99         let _v = [&t; 32];
100         let _s = s.clone(); // ok
101         let _t = t.clone(); // ok
102     }
103
104     {
105         let _u = {
106             let u = Some(&s);
107             let _ = s.clone(); // ok
108             u
109         };
110         let _s = s.clone(); // ok
111     }
112
113     {
114         use std::convert::identity as id;
115         let _u = id(id(&s));
116         let _s = s.clone(); // ok, `u` borrows `s`
117     }
118
119     let _s = s.clone();
120     let _t = t.clone();
121
122     #[derive(Clone)]
123     struct Foo {
124         x: usize,
125     }
126
127     {
128         let f = Foo { x: 123 };
129         let _x = Some(f.x);
130         let _f = f.clone();
131     }
132
133     {
134         let f = Foo { x: 123 };
135         let _x = &f.x;
136         let _f = f.clone(); // ok
137     }
138 }
139
140 fn not_consumed() {
141     let x = std::path::PathBuf::from("home");
142     let y = x.clone().join("matthias");
143     // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is
144     // redundant. (It also does not consume the PathBuf)
145
146     println!("x: {:?}, y: {:?}", x, y);
147
148     let mut s = String::new();
149     s.clone().push_str("foo"); // OK, removing this `clone()` will change the behavior.
150     s.push_str("bar");
151     assert_eq!(s, "bar");
152
153     let t = Some(s);
154     // OK
155     if let Some(x) = t.clone() {
156         println!("{}", x);
157     }
158     if let Some(x) = t {
159         println!("{}", x);
160     }
161 }
162
163 #[allow(clippy::clone_on_copy)]
164 fn issue_5405() {
165     let a: [String; 1] = [String::from("foo")];
166     let _b: String = a[0].clone();
167
168     let c: [usize; 2] = [2, 3];
169     let _d: usize = c[1].clone();
170 }
171
172 fn manually_drop() {
173     use std::mem::ManuallyDrop;
174     use std::sync::Arc;
175
176     let a = ManuallyDrop::new(Arc::new("Hello!".to_owned()));
177     let _ = a.clone(); // OK
178
179     let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a));
180     unsafe {
181         Arc::from_raw(p);
182         Arc::from_raw(p);
183     }
184 }