Skip to content

Commit ab3946d

Browse files
committed
Fixes #5405: redundant clone false positive with arrays
Check whether slice elements implement Copy before suggesting to drop the clone method
1 parent af5940b commit ab3946d

File tree

4 files changed

+36
-11
lines changed

4 files changed

+36
-11
lines changed

clippy_lints/src/redundant_clone.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,21 @@ fn base_local_and_movability<'tcx>(
341341
let mut deref = false;
342342
// Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
343343
let mut field = false;
344+
// If projection is a slice index then clone can be removed only if the
345+
// underlying type implements Copy
346+
let mut slice = false;
344347

345348
let PlaceRef { local, mut projection } = place.as_ref();
346349
while let [base @ .., elem] = projection {
347350
projection = base;
348351
deref |= matches!(elem, mir::ProjectionElem::Deref);
349352
field |= matches!(elem, mir::ProjectionElem::Field(..))
350353
&& has_drop(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
354+
slice |= matches!(elem, mir::ProjectionElem::Index(..))
355+
&& !is_copy(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
351356
}
352357

353-
Some((local, deref || field))
358+
Some((local, deref || field || slice))
354359
}
355360

356361
struct LocalUseVisitor {

tests/ui/redundant_clone.fixed

+10
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fn main() {
5151
cannot_move_from_type_with_drop();
5252
borrower_propagation();
5353
not_consumed();
54+
issue_5405();
5455
}
5556

5657
#[derive(Clone)]
@@ -160,3 +161,12 @@ fn not_consumed() {
160161
println!("{}", x);
161162
}
162163
}
164+
165+
#[allow(clippy::clone_on_copy)]
166+
fn issue_5405() {
167+
let a: [String; 1] = [String::from("foo")];
168+
let _b: String = a[0].clone();
169+
170+
let c: [usize; 2] = [2, 3];
171+
let _d: usize = c[1].clone();
172+
}

tests/ui/redundant_clone.rs

+10
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fn main() {
5151
cannot_move_from_type_with_drop();
5252
borrower_propagation();
5353
not_consumed();
54+
issue_5405();
5455
}
5556

5657
#[derive(Clone)]
@@ -160,3 +161,12 @@ fn not_consumed() {
160161
println!("{}", x);
161162
}
162163
}
164+
165+
#[allow(clippy::clone_on_copy)]
166+
fn issue_5405() {
167+
let a: [String; 1] = [String::from("foo")];
168+
let _b: String = a[0].clone();
169+
170+
let c: [usize; 2] = [2, 3];
171+
let _d: usize = c[1].clone();
172+
}

tests/ui/redundant_clone.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -108,61 +108,61 @@ LL | let _t = tup.0.clone();
108108
| ^^^^^
109109

110110
error: redundant clone
111-
--> $DIR/redundant_clone.rs:60:22
111+
--> $DIR/redundant_clone.rs:61:22
112112
|
113113
LL | (a.clone(), a.clone())
114114
| ^^^^^^^^ help: remove this
115115
|
116116
note: this value is dropped without further use
117-
--> $DIR/redundant_clone.rs:60:21
117+
--> $DIR/redundant_clone.rs:61:21
118118
|
119119
LL | (a.clone(), a.clone())
120120
| ^
121121

122122
error: redundant clone
123-
--> $DIR/redundant_clone.rs:120:15
123+
--> $DIR/redundant_clone.rs:121:15
124124
|
125125
LL | let _s = s.clone();
126126
| ^^^^^^^^ help: remove this
127127
|
128128
note: this value is dropped without further use
129-
--> $DIR/redundant_clone.rs:120:14
129+
--> $DIR/redundant_clone.rs:121:14
130130
|
131131
LL | let _s = s.clone();
132132
| ^
133133

134134
error: redundant clone
135-
--> $DIR/redundant_clone.rs:121:15
135+
--> $DIR/redundant_clone.rs:122:15
136136
|
137137
LL | let _t = t.clone();
138138
| ^^^^^^^^ help: remove this
139139
|
140140
note: this value is dropped without further use
141-
--> $DIR/redundant_clone.rs:121:14
141+
--> $DIR/redundant_clone.rs:122:14
142142
|
143143
LL | let _t = t.clone();
144144
| ^
145145

146146
error: redundant clone
147-
--> $DIR/redundant_clone.rs:131:19
147+
--> $DIR/redundant_clone.rs:132:19
148148
|
149149
LL | let _f = f.clone();
150150
| ^^^^^^^^ help: remove this
151151
|
152152
note: this value is dropped without further use
153-
--> $DIR/redundant_clone.rs:131:18
153+
--> $DIR/redundant_clone.rs:132:18
154154
|
155155
LL | let _f = f.clone();
156156
| ^
157157

158158
error: redundant clone
159-
--> $DIR/redundant_clone.rs:143:14
159+
--> $DIR/redundant_clone.rs:144:14
160160
|
161161
LL | let y = x.clone().join("matthias");
162162
| ^^^^^^^^ help: remove this
163163
|
164164
note: cloned value is neither consumed nor mutated
165-
--> $DIR/redundant_clone.rs:143:13
165+
--> $DIR/redundant_clone.rs:144:13
166166
|
167167
LL | let y = x.clone().join("matthias");
168168
| ^^^^^^^^^

0 commit comments

Comments
 (0)