Skip to content

Commit 7139436

Browse files
committed
add index checks for the slice in manual_slice_fill
1 parent 8c01600 commit 7139436

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

clippy_lints/src/loops/manual_slice_fill.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use clippy_utils::macros::span_is_local;
44
use clippy_utils::msrvs::{self, Msrv};
55
use clippy_utils::source::{HasSession, snippet_with_applicability};
66
use clippy_utils::ty::implements_trait;
7+
use clippy_utils::visitors::is_local_used;
78
use clippy_utils::{higher, peel_blocks_with_stmt, span_contains_comment};
89
use rustc_ast::ast::LitKind;
910
use rustc_ast::{RangeLimits, UnOp};
@@ -43,7 +44,7 @@ pub(super) fn check<'tcx>(
4344
&& let ExprKind::Block(..) = body.kind
4445
// Check if the body is an assignment to a slice element.
4546
&& let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind
46-
&& let ExprKind::Index(slice, _, _) = assignee.kind
47+
&& let ExprKind::Index(slice, idx, _) = assignee.kind
4748
// Check if `len()` is used for the range end.
4849
&& let ExprKind::MethodCall(path, recv,..) = end.kind
4950
&& path.ident.name == sym::len
@@ -58,6 +59,10 @@ pub(super) fn check<'tcx>(
5859
// The `fill` method requires that the slice's element type implements the `Clone` trait.
5960
&& let Some(clone_trait) = cx.tcx.lang_items().clone_trait()
6061
&& implements_trait(cx, cx.typeck_results().expr_ty(slice), clone_trait, &[])
62+
// https://github.com/rust-lang/rust-clippy/issues/14192
63+
&& let ExprKind::Path(Resolved(_, idx_path)) = idx.kind
64+
&& let Res::Local(idx_hir) = idx_path.res
65+
&& !is_local_used(cx, assignval, idx_hir)
6166
{
6267
sugg(cx, body, expr, slice.span, assignval.span);
6368
}

tests/ui/manual_slice_fill.fixed

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![warn(clippy::manual_slice_fill)]
2-
#![allow(clippy::needless_range_loop)]
2+
#![allow(clippy::needless_range_loop, clippy::useless_vec)]
33

44
macro_rules! assign_element {
55
($slice:ident, $index:expr) => {
@@ -99,3 +99,19 @@ fn should_not_lint() {
9999
*i = None;
100100
}
101101
}
102+
103+
fn issue_14192() {
104+
let mut tmp = vec![0; 3];
105+
106+
for i in 0..tmp.len() {
107+
tmp[i] = i;
108+
}
109+
110+
for i in 0..tmp.len() {
111+
tmp[i] = 2 + i;
112+
}
113+
114+
for i in 0..tmp.len() {
115+
tmp[0] = i;
116+
}
117+
}

tests/ui/manual_slice_fill.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![warn(clippy::manual_slice_fill)]
2-
#![allow(clippy::needless_range_loop)]
2+
#![allow(clippy::needless_range_loop, clippy::useless_vec)]
33

44
macro_rules! assign_element {
55
($slice:ident, $index:expr) => {
@@ -108,3 +108,19 @@ fn should_not_lint() {
108108
*i = None;
109109
}
110110
}
111+
112+
fn issue_14192() {
113+
let mut tmp = vec![0; 3];
114+
115+
for i in 0..tmp.len() {
116+
tmp[i] = i;
117+
}
118+
119+
for i in 0..tmp.len() {
120+
tmp[i] = 2 + i;
121+
}
122+
123+
for i in 0..tmp.len() {
124+
tmp[0] = i;
125+
}
126+
}

0 commit comments

Comments
 (0)