about summary refs log tree commit diff
diff options
context:
space:
mode:
authorShotaro Yamada <sinkuu@sinkuu.xyz>2018-12-10 15:59:21 +0900
committerShotaro Yamada <sinkuu@sinkuu.xyz>2018-12-10 15:59:21 +0900
commite7d18084fb8e6646489be545d20d050623d8d45d (patch)
tree50414cc1bc3c925f384f794aac922c4088ae974e
parentfd9f5df36ca934405183ee8e7ba96b46b1f645f2 (diff)
downloadrust-e7d18084fb8e6646489be545d20d050623d8d45d.tar.gz
rust-e7d18084fb8e6646489be545d20d050623d8d45d.zip
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.
-rw-r--r--clippy_lints/src/redundant_clone.rs36
1 files changed, 21 insertions, 15 deletions
diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs
index 68b79869718..0d31129f30a 100644
--- a/clippy_lints/src/redundant_clone.rs
+++ b/clippy_lints/src/redundant_clone.rs
@@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
                 mir,
                 arg,
                 from_borrow,
-                bbdata.statements.iter().rev()
+                bbdata.statements.iter()
             ));
 
             if from_borrow && cannot_move_out {
@@ -166,7 +166,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
                     mir,
                     pred_arg,
                     true,
-                    mir[ps[0]].statements.iter().rev()
+                    mir[ps[0]].statements.iter()
                 ));
                 if cannot_move_out {
                     continue;
@@ -257,23 +257,29 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
     mir: &mir::Mir<'tcx>,
     to: mir::Local,
     by_ref: bool,
-    mut stmts: impl Iterator<Item = &'a mir::Statement<'tcx>>,
+    stmts: impl DoubleEndedIterator<Item = &'a mir::Statement<'tcx>>,
 ) -> Option<(mir::Local, CannotMoveOut)> {
-    stmts.find_map(|stmt| {
-        if let mir::StatementKind::Assign(mir::Place::Local(local), v) = &stmt.kind {
-            if *local == to {
-                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);
+    stmts
+        .rev()
+        .find_map(|stmt| {
+            if let mir::StatementKind::Assign(mir::Place::Local(local), v) = &stmt.kind {
+                if *local == to {
+                    return Some(v);
                 }
             }
-        }
 
-        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