Skip to content

Commit bc5b8a3

Browse files
committed
fix: check bases does not contain reference to loop index
1 parent cf4dd10 commit bc5b8a3

File tree

3 files changed

+10
-22
lines changed

3 files changed

+10
-22
lines changed

clippy_lints/src/loops/manual_memcpy.rs

+4-19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::source::snippet;
44
use clippy_utils::sugg::Sugg;
55
use clippy_utils::ty::is_copy;
6+
use clippy_utils::usage::local_used_in;
67
use clippy_utils::{get_enclosing_block, higher, path_to_local, sugg};
78
use rustc_ast::ast;
89
use rustc_errors::Applicability;
@@ -59,13 +60,13 @@ pub(super) fn check<'tcx>(
5960
let rhs = fetch_cloned_expr(rhs);
6061
if let ExprKind::Index(base_left, idx_left, _) = lhs.kind
6162
&& let ExprKind::Index(base_right, idx_right, _) = rhs.kind
62-
&& is_index_suggestable(base_left) && is_index_suggestable(base_right)
6363
&& let Some(ty) = get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_left))
6464
&& get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some()
6565
&& let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts)
6666
&& let Some((start_right, offset_right)) = get_details_from_idx(cx, idx_right, &starts)
67-
68-
// Source and destination must be different
67+
&& !local_used_in(cx, canonical_id, base_left)
68+
&& !local_used_in(cx, canonical_id, base_right)
69+
// Source and destination must be different
6970
&& path_to_local(base_left) != path_to_local(base_right)
7071
{
7172
Some((
@@ -487,19 +488,3 @@ fn is_array_length_equal_to_range(cx: &LateContext<'_>, start: &Expr<'_>, end: &
487488
false
488489
}
489490
}
490-
491-
// Returns true if index is suggestable
492-
// i.e. Returns false if patterns are Index(Path(_), Path(_)) or Index(Index(_, _, _), Path(_))
493-
fn is_index_suggestable(expr: &Expr<'_>) -> bool {
494-
if let ExprKind::Index(left_expr, right_expr, _) = expr.kind {
495-
// Index(Path(_), Path(_), _) returns false
496-
if matches!(left_expr.kind, ExprKind::Path(_)) {
497-
return !matches!(right_expr.kind, ExprKind::Path(_));
498-
}
499-
500-
// Nested Index pattern
501-
return is_index_suggestable(left_expr) && !matches!(right_expr.kind, ExprKind::Path(_));
502-
}
503-
504-
true
505-
}

tests/ui/manual_memcpy/without_loop_counters.rs

+3
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
161161

162162
// Don't trigger lint for following multi-dimension arrays
163163
let src = [[0; 5]; 5];
164+
for i in 0..4 {
165+
dst[i] = src[i + 1][i];
166+
}
164167
for i in 0..5 {
165168
dst[i] = src[i][i];
166169
}

tests/ui/manual_memcpy/without_loop_counters.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ LL | | }
145145
| |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);`
146146

147147
error: it looks like you're manually copying between slices
148-
--> tests/ui/manual_memcpy/without_loop_counters.rs:201:5
148+
--> tests/ui/manual_memcpy/without_loop_counters.rs:204:5
149149
|
150150
LL | / for i in 0..5 {
151151
LL | |
@@ -154,7 +154,7 @@ LL | | }
154154
| |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);`
155155

156156
error: it looks like you're manually copying between slices
157-
--> tests/ui/manual_memcpy/without_loop_counters.rs:207:5
157+
--> tests/ui/manual_memcpy/without_loop_counters.rs:210:5
158158
|
159159
LL | / for i in 0..5 {
160160
LL | |
@@ -163,7 +163,7 @@ LL | | }
163163
| |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);`
164164

165165
error: it looks like you're manually copying between slices
166-
--> tests/ui/manual_memcpy/without_loop_counters.rs:215:5
166+
--> tests/ui/manual_memcpy/without_loop_counters.rs:218:5
167167
|
168168
LL | / for i in 0..src.len() {
169169
LL | |

0 commit comments

Comments
 (0)