@@ -6,6 +6,7 @@ use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts};
6
6
use clippy_utils:: { get_parent_expr, is_trait_method, match_def_path, path_to_local, paths} ;
7
7
use if_chain:: if_chain;
8
8
use rustc_errors:: Applicability ;
9
+ use rustc_hir:: def:: DefKind ;
9
10
use rustc_hir:: def_id:: DefId ;
10
11
use rustc_hir:: { BindingAnnotation , Expr , ExprKind , HirId , MatchSource , Node , PatKind } ;
11
12
use rustc_lint:: { LateContext , LateLintPass } ;
@@ -102,6 +103,17 @@ fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -
102
103
( expr, depth)
103
104
}
104
105
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
+
105
117
#[ expect( clippy:: too_many_lines) ]
106
118
impl < ' tcx > LateLintPass < ' tcx > for UselessConversion {
107
119
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) {
@@ -156,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
156
168
&& let Some ( did) = cx. qpath_res ( qpath, recv. hir_id ) . opt_def_id ( )
157
169
// make sure that the path indeed points to a fn-like item, so that
158
170
// `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) =>
160
172
{
161
173
Some ( ( did, args, MethodOrFunction :: Function ) )
162
174
}
@@ -174,6 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
174
186
&& let Some ( & into_iter_param) = sig. inputs ( ) . get ( kind. param_pos ( arg_pos) )
175
187
&& let ty:: Param ( param) = into_iter_param. kind ( )
176
188
&& let Some ( span) = into_iter_bound ( cx, parent_fn_did, into_iter_did, param. index )
189
+ && !is_macro_argument ( cx, e)
177
190
{
178
191
// Get the "innermost" `.into_iter()` call, e.g. given this expression:
179
192
// `foo.into_iter().into_iter()`
0 commit comments