mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-14 17:07:17 +00:00
Auto merge of #12380 - Ethiraric:fix-12358, r=llogiq
[`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 #12358 ---- changelog: [`redundant_closure_call`]: If `x!()` returns a closure, don't suggest replacing `x!()()` with `x!()`
This commit is contained in:
commit
139191b8b7
3 changed files with 43 additions and 0 deletions
|
@ -159,6 +159,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
|
||||||
// ^^ we only want to lint for this call (but we walk up the calls to consider both calls).
|
// ^^ we only want to lint for this call (but we walk up the calls to consider both calls).
|
||||||
// without this check, we'd end up linting twice.
|
// without this check, we'd end up linting twice.
|
||||||
&& !matches!(recv.kind, hir::ExprKind::Call(..))
|
&& !matches!(recv.kind, hir::ExprKind::Call(..))
|
||||||
|
// Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is
|
||||||
|
// the same as the one the call is in.
|
||||||
|
// For instance, let's assume `x!()` returns a closure:
|
||||||
|
// B ---v
|
||||||
|
// x!()()
|
||||||
|
// ^- A
|
||||||
|
// The call happens in the expansion `A`, while the closure originates from the expansion `B`.
|
||||||
|
// We don't want to suggest replacing `x!()()` with `x!()`.
|
||||||
|
&& recv.span.ctxt().outer_expn() == expr.span.ctxt().outer_expn()
|
||||||
&& let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
|
&& let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
|
||||||
&& let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
|
&& let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
|
||||||
// outside macros we lint properly. Inside macros, we lint only ||() style closures.
|
// outside macros we lint properly. Inside macros, we lint only ||() style closures.
|
||||||
|
|
|
@ -111,3 +111,20 @@ fn fp_11274() {
|
||||||
}
|
}
|
||||||
m!(|x| println!("{x}"));
|
m!(|x| println!("{x}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
|
||||||
|
// triggers the lint.
|
||||||
|
fn issue_12358() {
|
||||||
|
macro_rules! make_closure {
|
||||||
|
() => {
|
||||||
|
(|| || {})
|
||||||
|
};
|
||||||
|
(x) => {
|
||||||
|
make_closure!()()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
|
||||||
|
// different.
|
||||||
|
make_closure!(x)();
|
||||||
|
}
|
||||||
|
|
|
@ -111,3 +111,20 @@ fn fp_11274() {
|
||||||
}
|
}
|
||||||
m!(|x| println!("{x}"));
|
m!(|x| println!("{x}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
|
||||||
|
// triggers the lint.
|
||||||
|
fn issue_12358() {
|
||||||
|
macro_rules! make_closure {
|
||||||
|
() => {
|
||||||
|
(|| || {})
|
||||||
|
};
|
||||||
|
(x) => {
|
||||||
|
make_closure!()()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
|
||||||
|
// different.
|
||||||
|
make_closure!(x)();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue