Skip to content

Commit

Permalink
Added check for type unification with the iter
Browse files Browse the repository at this point in the history
  • Loading branch information
its-the-shrimp committed May 21, 2024
1 parent b31625c commit 7439ecb
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 3 deletions.
10 changes: 7 additions & 3 deletions clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>) {
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/iter_on_empty_collections.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/iter_on_empty_collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 7439ecb

Please sign in to comment.