manual_slice_fill: do not initialize from the iterator (#14191)

```rust
let mut tmp = vec![1, 2, 3];
for b in &mut tmp {
    *b = !*b;
}
```

must not suggest the invalid `tmp.fill(!*b)`.

In addition, there is another commit which cleans up two function calls
with no effect.

Fix #14189

changelog: [`manual_slice_fill`]: ensure that the initialization
expression doesn't reference the iterator
This commit is contained in:
dswij 2025-02-22 15:28:15 +00:00 committed by GitHub
commit d92da0fb32
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 3 deletions

View file

@ -1,6 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
use clippy_utils::macros::span_is_local;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{HasSession, snippet_with_applicability};
use clippy_utils::ty::implements_trait;
@ -55,7 +54,6 @@ pub(super) fn check<'tcx>(
&& !assignval.span.from_expansion()
// It is generally not equivalent to use the `fill` method if `assignval` can have side effects
&& switch_to_eager_eval(cx, assignval)
&& span_is_local(assignval.span)
// The `fill` method requires that the slice's element type implements the `Clone` trait.
&& let Some(clone_trait) = cx.tcx.lang_items().clone_trait()
&& implements_trait(cx, cx.typeck_results().expr_ty(slice), clone_trait, &[])
@ -78,7 +76,8 @@ pub(super) fn check<'tcx>(
&& local == pat.hir_id
&& !assignval.span.from_expansion()
&& switch_to_eager_eval(cx, assignval)
&& span_is_local(assignval.span)
// `assignval` must not reference the iterator
&& !is_local_used(cx, assignval, local)
// The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait.
&& let Some(clone_trait) = cx.tcx.lang_items().clone_trait()
&& implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[])