Only check the assignment found at last

If there are more than one such assignment, the last one may be
the one supplied to `clone` method.
Makes `find_stmt_assigns_to` internally reverses the iterator to make
the intent to "iterate statements backward" clear.
This commit is contained in:
Shotaro Yamada 2018-12-10 15:59:21 +09:00
parent fd9f5df36c
commit e7d18084fb

View File

@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
mir, mir,
arg, arg,
from_borrow, from_borrow,
bbdata.statements.iter().rev() bbdata.statements.iter()
)); ));
if from_borrow && cannot_move_out { if from_borrow && cannot_move_out {
@ -166,7 +166,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
mir, mir,
pred_arg, pred_arg,
true, true,
mir[ps[0]].statements.iter().rev() mir[ps[0]].statements.iter()
)); ));
if cannot_move_out { if cannot_move_out {
continue; continue;
@ -257,23 +257,29 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
mir: &mir::Mir<'tcx>, mir: &mir::Mir<'tcx>,
to: mir::Local, to: mir::Local,
by_ref: bool, by_ref: bool,
mut stmts: impl Iterator<Item = &'a mir::Statement<'tcx>>, stmts: impl DoubleEndedIterator<Item = &'a mir::Statement<'tcx>>,
) -> Option<(mir::Local, CannotMoveOut)> { ) -> Option<(mir::Local, CannotMoveOut)> {
stmts.find_map(|stmt| { stmts
if let mir::StatementKind::Assign(mir::Place::Local(local), v) = &stmt.kind { .rev()
if *local == to { .find_map(|stmt| {
if by_ref { if let mir::StatementKind::Assign(mir::Place::Local(local), v) = &stmt.kind {
if let mir::Rvalue::Ref(_, _, ref place) = **v { if *local == to {
return base_local_and_movability(cx, mir, place); return Some(v);
}
} else if let mir::Rvalue::Use(mir::Operand::Copy(ref place)) = **v {
return base_local_and_movability(cx, mir, place);
} }
} }
}
None None
}) })
.and_then(|v| {
if by_ref {
if let mir::Rvalue::Ref(_, _, ref place) = **v {
return base_local_and_movability(cx, mir, place);
}
} else if let mir::Rvalue::Use(mir::Operand::Copy(ref place)) = **v {
return base_local_and_movability(cx, mir, place);
}
None
})
} }
/// Extracts and returns the undermost base `Local` of given `place`. Returns `place` itself /// Extracts and returns the undermost base `Local` of given `place`. Returns `place` itself