about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/loops.rs18
-rw-r--r--tests/ui/manual_memcpy/with_loop_counters.rs7
-rw-r--r--tests/ui/manual_memcpy/with_loop_counters.stderr11
3 files changed, 29 insertions, 7 deletions
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index 2ae5a9acb75..ea40c2af4f7 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -1014,14 +1014,20 @@ fn get_assignments<'a: 'c, 'tcx: 'c, 'c>(
         .iter()
         .filter_map(move |stmt| match stmt.kind {
             StmtKind::Local(..) | StmtKind::Item(..) => None,
-            StmtKind::Expr(e) | StmtKind::Semi(e) => if_chain! {
-                if let ExprKind::AssignOp(_, var, _) = e.kind;
-                // skip StartKind::Range
-                if loop_counters.iter().skip(1).any(|counter| Some(counter.id) == var_def_id(cx, var));
-                then { None } else { Some(e) }
-            },
+            StmtKind::Expr(e) | StmtKind::Semi(e) => Some(e),
         })
         .chain((*expr).into_iter())
+        .filter(move |e| {
+            if let ExprKind::AssignOp(_, place, _) = e.kind {
+                !loop_counters
+                    .iter()
+                    // skip StartKind::Range
+                    .skip(1)
+                    .any(|counter| same_var(cx, place, counter.id))
+            } else {
+                true
+            }
+        })
         .map(get_assignment)
 }
 
diff --git a/tests/ui/manual_memcpy/with_loop_counters.rs b/tests/ui/manual_memcpy/with_loop_counters.rs
index a49ba9eb10a..70873c9e994 100644
--- a/tests/ui/manual_memcpy/with_loop_counters.rs
+++ b/tests/ui/manual_memcpy/with_loop_counters.rs
@@ -59,6 +59,13 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32])
         dst[count] = src[i + 2];
         count += 1;
     }
+
+    // make sure incrementing expressions without semicolons at the end of loops are handled correctly.
+    let mut count = 0;
+    for i in 3..src.len() {
+        dst[i] = src[count];
+        count += 1
+    }
 }
 
 fn main() {}
diff --git a/tests/ui/manual_memcpy/with_loop_counters.stderr b/tests/ui/manual_memcpy/with_loop_counters.stderr
index 24393ad9b4d..598c881b4d6 100644
--- a/tests/ui/manual_memcpy/with_loop_counters.stderr
+++ b/tests/ui/manual_memcpy/with_loop_counters.stderr
@@ -89,5 +89,14 @@ LL | |         count += 1;
 LL | |     }
    | |_____^ help: try replacing the loop by: `dst[(0 << 1)..((1 << 1) + (0 << 1))].clone_from_slice(&src[2..((1 << 1) + 2)]);`
 
-error: aborting due to 9 previous errors
+error: it looks like you're manually copying between slices
+  --> $DIR/with_loop_counters.rs:65:5
+   |
+LL | /     for i in 3..src.len() {
+LL | |         dst[i] = src[count];
+LL | |         count += 1
+LL | |     }
+   | |_____^ help: try replacing the loop by: `dst[3..src.len()].clone_from_slice(&src[..(src.len() - 3)]);`
+
+error: aborting due to 10 previous errors