about summary refs log tree commit diff
diff options
context:
space:
mode:
authordswij <dharmasw@outlook.com>2025-02-22 15:28:15 +0000
committerGitHub <noreply@github.com>2025-02-22 15:28:15 +0000
commitd92da0fb322e833e481a4c50f0f73b7b27829546 (patch)
tree5c801b6494c2176385122b075779a6b6f0672bf0
parentd5488b3b631826269e2e6ea5f67a31b7d3fa7d0c (diff)
parent44aa75fd2aa94850103215c8e67b0d0baa24b6b7 (diff)
downloadrust-d92da0fb322e833e481a4c50f0f73b7b27829546.tar.gz
rust-d92da0fb322e833e481a4c50f0f73b7b27829546.zip
`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
-rw-r--r--clippy_lints/src/loops/manual_slice_fill.rs5
-rw-r--r--tests/ui/manual_slice_fill.fixed8
-rw-r--r--tests/ui/manual_slice_fill.rs8
3 files changed, 18 insertions, 3 deletions
diff --git a/clippy_lints/src/loops/manual_slice_fill.rs b/clippy_lints/src/loops/manual_slice_fill.rs
index bece83eaf3d..a9764178862 100644
--- a/clippy_lints/src/loops/manual_slice_fill.rs
+++ b/clippy_lints/src/loops/manual_slice_fill.rs
@@ -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, &[])
diff --git a/tests/ui/manual_slice_fill.fixed b/tests/ui/manual_slice_fill.fixed
index 80e271117fc..bba863247f5 100644
--- a/tests/ui/manual_slice_fill.fixed
+++ b/tests/ui/manual_slice_fill.fixed
@@ -115,3 +115,11 @@ fn issue_14192() {
         tmp[0] = i;
     }
 }
+
+fn issue14189() {
+    // Should not lint because `!*b` is not constant
+    let mut tmp = vec![1, 2, 3];
+    for b in &mut tmp {
+        *b = !*b;
+    }
+}
diff --git a/tests/ui/manual_slice_fill.rs b/tests/ui/manual_slice_fill.rs
index f758f47bbcb..44c60dc40f0 100644
--- a/tests/ui/manual_slice_fill.rs
+++ b/tests/ui/manual_slice_fill.rs
@@ -128,3 +128,11 @@ fn issue_14192() {
         tmp[0] = i;
     }
 }
+
+fn issue14189() {
+    // Should not lint because `!*b` is not constant
+    let mut tmp = vec![1, 2, 3];
+    for b in &mut tmp {
+        *b = !*b;
+    }
+}