@@ -6,6 +6,7 @@ use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts};
66use clippy_utils:: { get_parent_expr, is_trait_method, match_def_path, path_to_local, paths} ;
77use if_chain:: if_chain;
88use rustc_errors:: Applicability ;
9+ use rustc_hir:: def:: DefKind ;
910use rustc_hir:: def_id:: DefId ;
1011use rustc_hir:: { BindingAnnotation , Expr , ExprKind , HirId , MatchSource , Node , PatKind } ;
1112use rustc_lint:: { LateContext , LateLintPass } ;
@@ -102,6 +103,17 @@ fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -
102103 ( expr, depth)
103104}
104105
106+ /// Checks if the given `expr` is an argument of a macro invocation.
107+ /// This is a slow-ish operation, so consider calling this late
108+ /// to avoid slowing down the lint in the happy path when not emitting a warning
109+ fn is_macro_argument ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
110+ if let Some ( parent) = get_parent_expr ( cx, expr) {
111+ parent. span . from_expansion ( ) || is_macro_argument ( cx, parent)
112+ } else {
113+ false
114+ }
115+ }
116+
105117#[ expect( clippy:: too_many_lines) ]
106118impl < ' tcx > LateLintPass < ' tcx > for UselessConversion {
107119 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) {
@@ -156,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
156168 && let Some ( did) = cx. qpath_res ( qpath, recv. hir_id ) . opt_def_id ( )
157169 // make sure that the path indeed points to a fn-like item, so that
158170 // `fn_sig` does not ICE. (see #11065)
159- && cx. tcx . opt_def_kind ( did) . is_some_and ( |k| k . is_fn_like ( ) ) =>
171+ && cx. tcx . opt_def_kind ( did) . is_some_and ( DefKind :: is_fn_like) =>
160172 {
161173 Some ( ( did, args, MethodOrFunction :: Function ) )
162174 }
@@ -174,6 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
174186 && let Some ( & into_iter_param) = sig. inputs ( ) . get ( kind. param_pos ( arg_pos) )
175187 && let ty:: Param ( param) = into_iter_param. kind ( )
176188 && let Some ( span) = into_iter_bound ( cx, parent_fn_did, into_iter_did, param. index )
189+ && !is_macro_argument ( cx, e)
177190 {
178191 // Get the "innermost" `.into_iter()` call, e.g. given this expression:
179192 // `foo.into_iter().into_iter()`
0 commit comments