Auto merge of #5997 - giraffate:fix_fp_about_clone_in_same_item_push, r=ebroto

Fix FP in `same_item_push`

Don't emit a lint when the pushed item doesn't have Clone trait

Fix #5979

changelog: Fix FP in `same_item_push` not to emit a lint when the pushed item doesn't have Clone trait
This commit is contained in:
bors 2020-09-05 20:27:17 +00:00
commit e9440cbcde
2 changed files with 61 additions and 35 deletions

View file

@ -1140,6 +1140,14 @@ fn detect_same_item_push<'tcx>(
walk_expr(&mut same_item_push_visitor, body);
if same_item_push_visitor.should_lint {
if let Some((vec, pushed_item)) = same_item_push_visitor.vec_push {
let vec_ty = cx.typeck_results().expr_ty(vec);
let ty = vec_ty.walk().nth(1).unwrap().expect_ty();
if cx
.tcx
.lang_items()
.clone_trait()
.map_or(false, |id| implements_trait(cx, ty, id, &[]))
{
// Make sure that the push does not involve possibly mutating values
if let PatKind::Wild = pat.kind {
let vec_str = snippet_with_macro_callsite(cx, vec.span, "");
@ -1182,6 +1190,7 @@ fn detect_same_item_push<'tcx>(
}
}
}
}
/// Checks for looping over a range and then indexing a sequence with it.
/// The iteratee must be a range literal.

View file

@ -94,4 +94,21 @@ fn main() {
vec13.push(item);
item += 10;
}
// Fix #5979
let mut vec14: Vec<std::fs::File> = Vec::new();
for _ in 0..10 {
vec14.push(std::fs::File::open("foobar").unwrap());
}
// Fix #5979
#[derive(Clone)]
struct S {}
trait T {}
impl T for S {}
let mut vec15: Vec<Box<dyn T>> = Vec::new();
for _ in 0..10 {
vec15.push(Box::new(S {}));
}
}