about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/methods/iter_on_single_or_empty_collections.rs10
-rw-r--r--tests/ui/iter_on_empty_collections.fixed4
-rw-r--r--tests/ui/iter_on_empty_collections.rs4
3 files changed, 15 insertions, 3 deletions
diff --git a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 1bf323cf3c7..f4397212cf6 100644
--- a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -37,14 +37,18 @@ fn is_arg_ty_unified_in_fn<'tcx>(
 ) -> bool {
     let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity();
     let arg_id_in_args = args.into_iter().position(|e| e.hir_id == arg_id).unwrap();
-    let arg_ty_in_args = fn_sig.input(arg_id_in_args);
+    let arg_ty_in_args = fn_sig.input(arg_id_in_args).skip_binder();
 
     cx.tcx.predicates_of(fn_id).predicates.iter().any(|(clause, _)| {
         clause
             .as_projection_clause()
             .and_then(|p| p.map_bound(|p| p.term.ty()).transpose())
-            .is_some_and(|ty| ty == arg_ty_in_args)
-    })
+            .is_some_and(|ty| ty.skip_binder() == arg_ty_in_args)
+    }) || fn_sig
+        .inputs()
+        .iter()
+        .enumerate()
+        .any(|(i, ty)| i != arg_id_in_args && ty.skip_binder().walk().any(|arg| arg.as_type() == Some(arg_ty_in_args)))
 }
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method_name: &str, recv: &'tcx Expr<'tcx>) {
diff --git a/tests/ui/iter_on_empty_collections.fixed b/tests/ui/iter_on_empty_collections.fixed
index 4b5746c7b6f..0f28b48d9ab 100644
--- a/tests/ui/iter_on_empty_collections.fixed
+++ b/tests/ui/iter_on_empty_collections.fixed
@@ -38,6 +38,10 @@ fn array() {
     for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) {
         println!("{i}");
     }
+
+    // Same as above, but when there are no predicates that mention the collection iter type.
+    let mut iter = [34, 228, 35].iter();
+    let _ = std::mem::replace(&mut iter, [].iter());
 }
 
 macro_rules! in_macros {
diff --git a/tests/ui/iter_on_empty_collections.rs b/tests/ui/iter_on_empty_collections.rs
index 737192d556d..702da514df7 100644
--- a/tests/ui/iter_on_empty_collections.rs
+++ b/tests/ui/iter_on_empty_collections.rs
@@ -38,6 +38,10 @@ fn array() {
     for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) {
         println!("{i}");
     }
+
+    // Same as above, but when there are no predicates that mention the collection iter type.
+    let mut iter = [34, 228, 35].iter();
+    let _ = std::mem::replace(&mut iter, [].iter());
 }
 
 macro_rules! in_macros {