Skip to content

Commit 4c43aa7

Browse files
committed
Fix suggestion for async in redundant_closure_call
Fix redundant_closure_call for single-expression async closures Add Sugg::asyncify Use Sugg for redundant_closure_call implementation
1 parent aa0706b commit 4c43aa7

File tree

5 files changed

+109
-8
lines changed

5 files changed

+109
-8
lines changed

clippy_lints/src/redundant_closure_call.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
2-
use clippy_utils::source::snippet_with_applicability;
2+
use clippy_utils::sugg::Sugg;
33
use if_chain::if_chain;
44
use rustc_ast::ast;
55
use rustc_ast::visit as ast_visit;
@@ -69,7 +69,7 @@ impl EarlyLintPass for RedundantClosureCall {
6969
if_chain! {
7070
if let ast::ExprKind::Call(ref paren, _) = expr.kind;
7171
if let ast::ExprKind::Paren(ref closure) = paren.kind;
72-
if let ast::ExprKind::Closure(_, _, _, _, ref decl, ref block, _) = closure.kind;
72+
if let ast::ExprKind::Closure(_, _, ref r#async, _, ref decl, ref block, _) = closure.kind;
7373
then {
7474
let mut visitor = ReturnVisitor::new();
7575
visitor.visit_expr(block);
@@ -81,10 +81,19 @@ impl EarlyLintPass for RedundantClosureCall {
8181
"try not to call a closure in the expression where it is declared",
8282
|diag| {
8383
if decl.inputs.is_empty() {
84-
let mut app = Applicability::MachineApplicable;
85-
let hint =
86-
snippet_with_applicability(cx, block.span, "..", &mut app).into_owned();
87-
diag.span_suggestion(expr.span, "try doing something like", hint, app);
84+
let app = Applicability::MachineApplicable;
85+
let mut hint = Sugg::ast(cx, block, "..");
86+
87+
if r#async.is_async() {
88+
// `async x` is a syntax error, so it becomes `async { x }`
89+
if !matches!(block.kind, ast::ExprKind::Block(_, _)) {
90+
hint = hint.blockify();
91+
}
92+
93+
hint = hint.asyncify();
94+
}
95+
96+
diag.span_suggestion(expr.span, "try doing something like", hint.to_string(), app);
8897
}
8998
},
9099
);

clippy_utils/src/sugg.rs

+6
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ impl<'a> Sugg<'a> {
315315
Sugg::NonParen(Cow::Owned(format!("{{ {} }}", self)))
316316
}
317317

318+
/// Convenience method to prefix the expression with the `async` keyword.
319+
/// Can be used after `blockify` to create an async block.
320+
pub fn asyncify(self) -> Sugg<'static> {
321+
Sugg::NonParen(Cow::Owned(format!("async {}", self)))
322+
}
323+
318324
/// Convenience method to create the `<lhs>..<rhs>` or `<lhs>...<rhs>`
319325
/// suggestion.
320326
pub fn range(self, end: &Self, limit: ast::RangeLimits) -> Sugg<'static> {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
// run-rustfix
22

3+
#![feature(async_closure)]
34
#![warn(clippy::redundant_closure_call)]
45
#![allow(unused)]
56

7+
async fn something() -> u32 {
8+
21
9+
}
10+
11+
async fn something_else() -> u32 {
12+
2
13+
}
14+
615
fn main() {
716
let a = 42;
17+
let b = async {
18+
let x = something().await;
19+
let y = something_else().await;
20+
x * y
21+
};
22+
let c = {
23+
let x = 21;
24+
let y = 2;
25+
x * y
26+
};
27+
let d = async { something().await };
828
}
+20
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
// run-rustfix
22

3+
#![feature(async_closure)]
34
#![warn(clippy::redundant_closure_call)]
45
#![allow(unused)]
56

7+
async fn something() -> u32 {
8+
21
9+
}
10+
11+
async fn something_else() -> u32 {
12+
2
13+
}
14+
615
fn main() {
716
let a = (|| 42)();
17+
let b = (async || {
18+
let x = something().await;
19+
let y = something_else().await;
20+
x * y
21+
})();
22+
let c = (|| {
23+
let x = 21;
24+
let y = 2;
25+
x * y
26+
})();
27+
let d = (async || something().await)();
828
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,56 @@
11
error: try not to call a closure in the expression where it is declared
2-
--> $DIR/redundant_closure_call_fixable.rs:7:13
2+
--> $DIR/redundant_closure_call_fixable.rs:16:13
33
|
44
LL | let a = (|| 42)();
55
| ^^^^^^^^^ help: try doing something like: `42`
66
|
77
= note: `-D clippy::redundant-closure-call` implied by `-D warnings`
88

9-
error: aborting due to previous error
9+
error: try not to call a closure in the expression where it is declared
10+
--> $DIR/redundant_closure_call_fixable.rs:17:13
11+
|
12+
LL | let b = (async || {
13+
| _____________^
14+
LL | | let x = something().await;
15+
LL | | let y = something_else().await;
16+
LL | | x * y
17+
LL | | })();
18+
| |________^
19+
|
20+
help: try doing something like
21+
|
22+
LL ~ let b = async {
23+
LL + let x = something().await;
24+
LL + let y = something_else().await;
25+
LL + x * y
26+
LL ~ };
27+
|
28+
29+
error: try not to call a closure in the expression where it is declared
30+
--> $DIR/redundant_closure_call_fixable.rs:22:13
31+
|
32+
LL | let c = (|| {
33+
| _____________^
34+
LL | | let x = 21;
35+
LL | | let y = 2;
36+
LL | | x * y
37+
LL | | })();
38+
| |________^
39+
|
40+
help: try doing something like
41+
|
42+
LL ~ let c = {
43+
LL + let x = 21;
44+
LL + let y = 2;
45+
LL + x * y
46+
LL ~ };
47+
|
48+
49+
error: try not to call a closure in the expression where it is declared
50+
--> $DIR/redundant_closure_call_fixable.rs:27:13
51+
|
52+
LL | let d = (async || something().await)();
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
54+
55+
error: aborting due to 4 previous errors
1056

0 commit comments

Comments
 (0)