@@ -7,7 +7,7 @@ use clippy_utils::{
77} ;
88use rustc_errors:: Applicability ;
99use rustc_hir:: def_id:: DefId ;
10- use rustc_hir:: { BindingMode , Expr , ExprKind , HirId , MatchSource , Node , PatKind } ;
10+ use rustc_hir:: { BindingMode , Expr , ExprKind , HirId , MatchSource , Mutability , Node , PatKind } ;
1111use rustc_infer:: infer:: TyCtxtInferExt ;
1212use rustc_infer:: traits:: Obligation ;
1313use rustc_lint:: { LateContext , LateLintPass } ;
@@ -298,6 +298,33 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
298298 // implements Copy, in which case .into_iter() returns a copy of the receiver and
299299 // cannot be safely omitted.
300300 if same_type_and_consts ( a, b) && !is_copy ( cx, b) {
301+ // Below we check if the parent method call meets the following conditions:
302+ // 1. First parameter is `&mut self` (requires mutable reference)
303+ // 2. Second parameter implements the `FnMut` trait (e.g., Iterator::any)
304+ // For methods satisfying these conditions (like any), .into_iter() must be preserved.
305+ if let Some ( parent) = get_parent_expr ( cx, e)
306+ && let ExprKind :: MethodCall ( _, recv, _, _) = parent. kind
307+ && recv. hir_id == e. hir_id
308+ && let Some ( def_id) = cx. typeck_results ( ) . type_dependent_def_id ( parent. hir_id )
309+ && let sig = cx. tcx . fn_sig ( def_id) . skip_binder ( ) . skip_binder ( )
310+ && let inputs = sig. inputs ( )
311+ && inputs. len ( ) >= 2
312+ && let Some ( self_ty) = inputs. first ( )
313+ && let ty:: Ref ( _, _, Mutability :: Mut ) = self_ty. kind ( )
314+ && let Some ( second_ty) = inputs. get ( 1 )
315+ && let predicates = cx. tcx . param_env ( def_id) . caller_bounds ( )
316+ && predicates. iter ( ) . any ( |pred| {
317+ if let ty:: ClauseKind :: Trait ( trait_pred) = pred. kind ( ) . skip_binder ( ) {
318+ trait_pred. self_ty ( ) == * second_ty
319+ && cx. tcx . lang_items ( ) . fn_mut_trait ( ) == Some ( trait_pred. def_id ( ) )
320+ } else {
321+ false
322+ }
323+ } )
324+ {
325+ return ;
326+ }
327+
301328 let sugg = snippet ( cx, recv. span , "<expr>" ) . into_owned ( ) ;
302329 span_lint_and_sugg (
303330 cx,
0 commit comments