Skip to content

Commit

Permalink
Fixes #5405: redundant clone false positive with arrays
Browse files Browse the repository at this point in the history
Check whether slice elements implement Copy before suggesting to drop
the clone method
  • Loading branch information
rabisg0 committed Apr 12, 2020
1 parent af5940b commit a0defdd
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 2 deletions.
7 changes: 6 additions & 1 deletion clippy_lints/src/redundant_clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,16 +341,21 @@ fn base_local_and_movability<'tcx>(
let mut deref = false;
// Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
let mut field = false;
// If projection is a slice index then clone can be removed only if the
// underlying type implements Copy
let mut slice = false;

let PlaceRef { local, mut projection } = place.as_ref();
while let [base @ .., elem] = projection {
projection = base;
deref |= matches!(elem, mir::ProjectionElem::Deref);
field |= matches!(elem, mir::ProjectionElem::Field(..))
&& has_drop(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
slice |= matches!(elem, mir::ProjectionElem::Index(..))
&& !is_copy(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
}

Some((local, deref || field))
Some((local, deref || field || slice))
}

struct LocalUseVisitor {
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/redundant_clone.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,11 @@ fn not_consumed() {
println!("{}", x);
}
}

fn issue_5405() {
let a: [String; 1] = [String::from("foo")];
let _b: String = a[0].clone();

let c: [usize; 2] = [2, 3];
let _d: usize = c[1].clone();
}
8 changes: 8 additions & 0 deletions tests/ui/redundant_clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,11 @@ fn not_consumed() {
println!("{}", x);
}
}

fn issue_5405() {
let a: [String; 1] = [String::from("foo")];
let _b: String = a[0].clone();

let c: [usize; 2] = [2, 3];
let _d: usize = c[1].clone();
}
10 changes: 9 additions & 1 deletion tests/ui/redundant_clone.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,13 @@ note: cloned value is neither consumed nor mutated
LL | let y = x.clone().join("matthias");
| ^^^^^^^^^

error: aborting due to 14 previous errors
error: using `clone` on a `Copy` type
--> $DIR/redundant_clone.rs:169:21
|
LL | let _d: usize = c[1].clone();
| ^^^^^^^^^^^^ help: try removing the `clone` call: `c[1]`
|
= note: `-D clippy::clone-on-copy` implied by `-D warnings`

error: aborting due to 15 previous errors

0 comments on commit a0defdd

Please sign in to comment.