Skip to content

Commit 0d59345

Browse files
committed
[redundant_closure_call]: Don't lint if closure origins from a macro
The following code used to trigger the lint: ```rs macro_rules! make_closure { () => { (|| {}) }; } make_closure!()(); ``` The lint would suggest to replace `make_closure!()()` with `make_closure!()`, which changes the code and removes the call to the closure from the macro. This commit fixes that. Fixes rust-lang#12358
1 parent af91e6e commit 0d59345

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

clippy_lints/src/redundant_closure_call.rs

+9
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
159159
// ^^ we only want to lint for this call (but we walk up the calls to consider both calls).
160160
// without this check, we'd end up linting twice.
161161
&& !matches!(recv.kind, hir::ExprKind::Call(..))
162+
// Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is
163+
// the same as the one the call is in.
164+
// For instance, let's assume `x!()` returns a closure:
165+
// B ---v
166+
// x!()()
167+
// ^- A
168+
// The call happens in the expansion `A`, while the closure originates from the expansion `B`.
169+
// We don't want to suggest replacing `x!()()` with `x!()`.
170+
&& recv.span.ctxt().outer_expn() == expr.span.ctxt().outer_expn()
162171
&& let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
163172
&& let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
164173
// outside macros we lint properly. Inside macros, we lint only ||() style closures.

tests/ui/redundant_closure_call_fixable.fixed

+17
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,20 @@ fn fp_11274() {
111111
}
112112
m!(|x| println!("{x}"));
113113
}
114+
115+
// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
116+
// triggers the lint.
117+
fn issue_12358() {
118+
macro_rules! make_closure {
119+
() => {
120+
(|| || {})
121+
};
122+
(x) => {
123+
make_closure!()()
124+
};
125+
}
126+
127+
// The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
128+
// different.
129+
make_closure!(x)();
130+
}

tests/ui/redundant_closure_call_fixable.rs

+17
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,20 @@ fn fp_11274() {
111111
}
112112
m!(|x| println!("{x}"));
113113
}
114+
115+
// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
116+
// triggers the lint.
117+
fn issue_12358() {
118+
macro_rules! make_closure {
119+
() => {
120+
(|| || {})
121+
};
122+
(x) => {
123+
make_closure!()()
124+
};
125+
}
126+
127+
// The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
128+
// different.
129+
make_closure!(x)();
130+
}

0 commit comments

Comments
 (0)