Skip to content

Commit acc13e2

Browse files
Make it into a structured suggestion, maybe-incorrect
1 parent d526ada commit acc13e2

File tree

4 files changed

+110
-2
lines changed

4 files changed

+110
-2
lines changed

compiler/rustc_lint/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}`
189189
190190
lint_closure_returning_async_block = closure returning async block can be made into an async closure
191191
.label = this async block can be removed, and the closure can be turned into an async closure
192+
.suggestion = turn this into an async closure
192193
193194
lint_command_line_source = `forbid` lint level was set on command line
194195

compiler/rustc_lint/src/async_closures.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_hir as hir;
2-
use rustc_macros::LintDiagnostic;
2+
use rustc_macros::{LintDiagnostic, Subdiagnostic};
33
use rustc_session::{declare_lint, declare_lint_pass};
44
use rustc_span::Span;
55

@@ -93,11 +93,19 @@ impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage {
9393
return;
9494
};
9595

96+
let deletion_span = cx.tcx.sess.source_map().span_extend_while_whitespace(async_decl_span);
97+
9698
cx.tcx.emit_node_span_lint(
9799
CLOSURE_RETURNING_ASYNC_BLOCK,
98100
expr.hir_id,
99101
fn_decl_span,
100-
ClosureReturningAsyncBlock { async_decl_span },
102+
ClosureReturningAsyncBlock {
103+
async_decl_span,
104+
sugg: AsyncClosureSugg {
105+
deletion_span,
106+
insertion_span: fn_decl_span.shrink_to_lo(),
107+
},
108+
},
101109
);
102110
}
103111
}
@@ -107,4 +115,15 @@ impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage {
107115
struct ClosureReturningAsyncBlock {
108116
#[label]
109117
async_decl_span: Span,
118+
#[subdiagnostic]
119+
sugg: AsyncClosureSugg,
120+
}
121+
122+
#[derive(Subdiagnostic)]
123+
#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
124+
struct AsyncClosureSugg {
125+
#[suggestion_part(code = "")]
126+
deletion_span: Span,
127+
#[suggestion_part(code = "async ")]
128+
insertion_span: Span,
110129
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ edition: 2021
2+
3+
#![feature(async_closure)]
4+
#![deny(closure_returning_async_block)]
5+
6+
fn main() {
7+
let x = || async {};
8+
//~^ ERROR closure returning async block can be made into an async closure
9+
10+
let x = || async move {};
11+
//~^ ERROR closure returning async block can be made into an async closure
12+
13+
let x = move || async move {};
14+
//~^ ERROR closure returning async block can be made into an async closure
15+
16+
let x = move || async {};
17+
//~^ ERROR closure returning async block can be made into an async closure
18+
19+
let x = || {{ async {} }};
20+
//~^ ERROR closure returning async block can be made into an async closure
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
error: closure returning async block can be made into an async closure
2+
--> $DIR/lint-closure-returning-async-block.rs:7:13
3+
|
4+
LL | let x = || async {};
5+
| ^^ ----- this async block can be removed, and the closure can be turned into an async closure
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/lint-closure-returning-async-block.rs:4:9
9+
|
10+
LL | #![deny(closure_returning_async_block)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
help: turn this into an async closure
13+
|
14+
LL - let x = || async {};
15+
LL + let x = async || {};
16+
|
17+
18+
error: closure returning async block can be made into an async closure
19+
--> $DIR/lint-closure-returning-async-block.rs:10:13
20+
|
21+
LL | let x = || async move {};
22+
| ^^ ---------- this async block can be removed, and the closure can be turned into an async closure
23+
|
24+
help: turn this into an async closure
25+
|
26+
LL - let x = || async move {};
27+
LL + let x = async || {};
28+
|
29+
30+
error: closure returning async block can be made into an async closure
31+
--> $DIR/lint-closure-returning-async-block.rs:13:13
32+
|
33+
LL | let x = move || async move {};
34+
| ^^^^^^^ ---------- this async block can be removed, and the closure can be turned into an async closure
35+
|
36+
help: turn this into an async closure
37+
|
38+
LL - let x = move || async move {};
39+
LL + let x = async move || {};
40+
|
41+
42+
error: closure returning async block can be made into an async closure
43+
--> $DIR/lint-closure-returning-async-block.rs:16:13
44+
|
45+
LL | let x = move || async {};
46+
| ^^^^^^^ ----- this async block can be removed, and the closure can be turned into an async closure
47+
|
48+
help: turn this into an async closure
49+
|
50+
LL - let x = move || async {};
51+
LL + let x = async move || {};
52+
|
53+
54+
error: closure returning async block can be made into an async closure
55+
--> $DIR/lint-closure-returning-async-block.rs:19:13
56+
|
57+
LL | let x = || {{ async {} }};
58+
| ^^ ----- this async block can be removed, and the closure can be turned into an async closure
59+
|
60+
help: turn this into an async closure
61+
|
62+
LL - let x = || {{ async {} }};
63+
LL + let x = async || {{ {} }};
64+
|
65+
66+
error: aborting due to 5 previous errors
67+

0 commit comments

Comments
 (0)