Skip to content

Commit 2713c50

Browse files
authored
fix: redundant_closure_call lint for closures with block (#15144)
Fixes #9583 When a closure with no parameters is called immediately after being defined, clippy can now suggest replacing the entire expression with just the closure's body. ---- changelog: [`redundant_closure_call`]: add fixes for closures with block
2 parents 8d688c6 + 9b4231d commit 2713c50

File tree

4 files changed

+61
-15
lines changed

4 files changed

+61
-15
lines changed

clippy_lints/src/redundant_closure_call.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use hir::Param;
55
use rustc_errors::Applicability;
66
use rustc_hir as hir;
77
use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
8-
use rustc_hir::{
9-
ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node, intravisit as hir_visit,
10-
};
8+
use rustc_hir::{ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, intravisit as hir_visit};
119
use rustc_lint::{LateContext, LateLintPass, LintContext};
1210
use rustc_middle::hir::nested_filter;
1311
use rustc_middle::ty;
@@ -198,15 +196,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
198196
hint = hint.asyncify();
199197
}
200198

201-
let is_in_fn_call_arg = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id) {
202-
matches!(expr.kind, ExprKind::Call(_, _))
203-
} else {
204-
false
205-
};
206-
207-
// avoid clippy::double_parens
208-
if !is_in_fn_call_arg {
209-
hint = hint.maybe_paren();
199+
// If the closure body is a block with a single expression, suggest just the inner expression,
200+
// not the block. Example: `(|| { Some(true) })()` should suggest
201+
// `Some(true)`
202+
if let ExprKind::Block(block, _) = body.kind
203+
&& block.stmts.is_empty()
204+
&& let Some(expr) = block.expr
205+
{
206+
hint = Sugg::hir_with_context(cx, expr, full_expr.span.ctxt(), "..", &mut applicability)
207+
.maybe_paren();
210208
}
211209

212210
diag.span_suggestion(full_expr.span, "try doing something like", hint, applicability);

tests/ui/redundant_closure_call_fixable.fixed

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn issue9956() {
6060
//~^ redundant_closure_call
6161

6262
// immediately calling only one closure, so we can't remove the other ones
63-
let a = (|| || 123);
63+
let a = || || 123;
6464
//~^ redundant_closure_call
6565
dbg!(a()());
6666

@@ -144,3 +144,15 @@ fn issue_12358() {
144144
// different.
145145
make_closure!(x)();
146146
}
147+
148+
#[rustfmt::skip]
149+
fn issue_9583() {
150+
Some(true) == Some(true);
151+
//~^ redundant_closure_call
152+
Some(true) == Some(true);
153+
//~^ redundant_closure_call
154+
Some(if 1 > 2 {1} else {2}) == Some(2);
155+
//~^ redundant_closure_call
156+
Some( 1 > 2 ) == Some(true);
157+
//~^ redundant_closure_call
158+
}

tests/ui/redundant_closure_call_fixable.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,15 @@ fn issue_12358() {
144144
// different.
145145
make_closure!(x)();
146146
}
147+
148+
#[rustfmt::skip]
149+
fn issue_9583() {
150+
(|| { Some(true) })() == Some(true);
151+
//~^ redundant_closure_call
152+
(|| Some(true))() == Some(true);
153+
//~^ redundant_closure_call
154+
(|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);
155+
//~^ redundant_closure_call
156+
(|| { Some( 1 > 2 ) })() == Some(true);
157+
//~^ redundant_closure_call
158+
}

tests/ui/redundant_closure_call_fixable.stderr

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ error: try not to call a closure in the expression where it is declared
9595
--> tests/ui/redundant_closure_call_fixable.rs:63:13
9696
|
9797
LL | let a = (|| || || 123)();
98-
| ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)`
98+
| ^^^^^^^^^^^^^^^^ help: try doing something like: `|| || 123`
9999

100100
error: try not to call a closure in the expression where it is declared
101101
--> tests/ui/redundant_closure_call_fixable.rs:68:13
@@ -145,5 +145,29 @@ error: try not to call a closure in the expression where it is declared
145145
LL | std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
146146
| ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32`
147147

148-
error: aborting due to 17 previous errors
148+
error: try not to call a closure in the expression where it is declared
149+
--> tests/ui/redundant_closure_call_fixable.rs:150:5
150+
|
151+
LL | (|| { Some(true) })() == Some(true);
152+
| ^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`
153+
154+
error: try not to call a closure in the expression where it is declared
155+
--> tests/ui/redundant_closure_call_fixable.rs:152:5
156+
|
157+
LL | (|| Some(true))() == Some(true);
158+
| ^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`
159+
160+
error: try not to call a closure in the expression where it is declared
161+
--> tests/ui/redundant_closure_call_fixable.rs:154:5
162+
|
163+
LL | (|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);
164+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(if 1 > 2 {1} else {2})`
165+
166+
error: try not to call a closure in the expression where it is declared
167+
--> tests/ui/redundant_closure_call_fixable.rs:156:5
168+
|
169+
LL | (|| { Some( 1 > 2 ) })() == Some(true);
170+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some( 1 > 2 )`
171+
172+
error: aborting due to 21 previous errors
149173

0 commit comments

Comments
 (0)