Skip to content

Commit 88adc95

Browse files
committed
manual_slice_fill: initializer must not reference the iterator
```rust let mut tmp = vec![1, 2, 3]; for b in &mut tmp { *b = !*b; } ``` must not suggest the invalid `tmp.fill(!*b)`.
1 parent 992a864 commit 88adc95

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

clippy_lints/src/loops/manual_slice_fill.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
use std::ops::ControlFlow;
2+
13
use clippy_utils::diagnostics::span_lint_and_sugg;
24
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
35
use clippy_utils::msrvs::{self, Msrv};
46
use clippy_utils::source::{HasSession, snippet_with_applicability};
57
use clippy_utils::ty::implements_trait;
6-
use clippy_utils::{higher, peel_blocks_with_stmt, span_contains_comment};
8+
use clippy_utils::visitors::for_each_expr;
9+
use clippy_utils::{higher, path_to_local_id, peel_blocks_with_stmt, span_contains_comment};
710
use rustc_ast::ast::LitKind;
811
use rustc_ast::{RangeLimits, UnOp};
912
use rustc_data_structures::packed::Pu128;
@@ -71,6 +74,10 @@ pub(super) fn check<'tcx>(
7174
&& local == pat.hir_id
7275
&& !assignval.span.from_expansion()
7376
&& switch_to_eager_eval(cx, assignval)
77+
// `assignval` must not reference the iterator
78+
&& for_each_expr(cx, assignval, |e|
79+
if path_to_local_id(e, local) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
80+
).is_none()
7481
// The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait.
7582
&& let Some(clone_trait) = cx.tcx.lang_items().clone_trait()
7683
&& implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[])

tests/ui/manual_slice_fill.fixed

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,11 @@ fn should_not_lint() {
9999
*i = None;
100100
}
101101
}
102+
103+
fn issue14189() {
104+
// Should not lint because `!*b` is not constant
105+
let mut tmp = vec![1, 2, 3];
106+
for b in &mut tmp {
107+
*b = !*b;
108+
}
109+
}

tests/ui/manual_slice_fill.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,11 @@ fn should_not_lint() {
108108
*i = None;
109109
}
110110
}
111+
112+
fn issue14189() {
113+
// Should not lint because `!*b` is not constant
114+
let mut tmp = vec![1, 2, 3];
115+
for b in &mut tmp {
116+
*b = !*b;
117+
}
118+
}

0 commit comments

Comments
 (0)