@@ -5,6 +5,7 @@ use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts};
5
5
use clippy_utils:: { get_parent_expr, is_trait_method, is_ty_alias, match_def_path, path_to_local, paths} ;
6
6
use if_chain:: if_chain;
7
7
use rustc_errors:: Applicability ;
8
+ use rustc_hir:: def:: DefKind ;
8
9
use rustc_hir:: def_id:: DefId ;
9
10
use rustc_hir:: { BindingAnnotation , Expr , ExprKind , HirId , MatchSource , Node , PatKind } ;
10
11
use rustc_lint:: { LateContext , LateLintPass } ;
@@ -101,6 +102,17 @@ fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -
101
102
( expr, depth)
102
103
}
103
104
105
+ /// Checks if the given `expr` is an argument of a macro invocation.
106
+ /// This is a slow-ish operation, so consider calling this late
107
+ /// to avoid slowing down the lint in the happy path when not emitting a warning
108
+ fn is_macro_argument ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
109
+ if let Some ( parent) = get_parent_expr ( cx, expr) {
110
+ parent. span . from_expansion ( ) || is_macro_argument ( cx, parent)
111
+ } else {
112
+ false
113
+ }
114
+ }
115
+
104
116
#[ expect( clippy:: too_many_lines) ]
105
117
impl < ' tcx > LateLintPass < ' tcx > for UselessConversion {
106
118
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) {
@@ -155,7 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
155
167
&& let Some ( did) = cx. qpath_res ( qpath, recv. hir_id ) . opt_def_id ( )
156
168
// make sure that the path indeed points to a fn-like item, so that
157
169
// `fn_sig` does not ICE. (see #11065)
158
- && cx. tcx . opt_def_kind ( did) . is_some_and ( |k| k . is_fn_like ( ) ) =>
170
+ && cx. tcx . opt_def_kind ( did) . is_some_and ( DefKind :: is_fn_like) =>
159
171
{
160
172
Some ( ( did, args, MethodOrFunction :: Function ) )
161
173
}
@@ -173,6 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
173
185
&& let Some ( & into_iter_param) = sig. inputs ( ) . get ( kind. param_pos ( arg_pos) )
174
186
&& let ty:: Param ( param) = into_iter_param. kind ( )
175
187
&& let Some ( span) = into_iter_bound ( cx, parent_fn_did, into_iter_did, param. index )
188
+ && !is_macro_argument ( cx, e)
176
189
{
177
190
// Get the "innermost" `.into_iter()` call, e.g. given this expression:
178
191
// `foo.into_iter().into_iter()`
0 commit comments