Skip to content

Commit a272d62

Browse files
committed
Implemented a compiler diagnostic for move async mistake
Ran the tidy check Following the diagnostic guide better Diagnostic generation is now relegated to its own function in the diagnostics module. Added tests Fixed the ui test
1 parent caeb333 commit a272d62

File tree

5 files changed

+61
-4
lines changed

5 files changed

+61
-4
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1912,4 +1912,22 @@ impl<'a> Parser<'a> {
19121912
*self = snapshot;
19131913
Err(err)
19141914
}
1915+
1916+
/// Get the diagnostics for the cases where `move async` is found.
1917+
///
1918+
/// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword
1919+
pub(super) fn incorrect_move_async_order_found(
1920+
&self,
1921+
move_async_span: Span,
1922+
) -> DiagnosticBuilder<'a> {
1923+
let mut err =
1924+
self.struct_span_err(move_async_span, "the order of `move` and `async` is incorrect");
1925+
err.span_suggestion_verbose(
1926+
move_async_span,
1927+
"try switching the order",
1928+
"async move".to_owned(),
1929+
Applicability::MaybeIncorrect,
1930+
);
1931+
err
1932+
}
19151933
}

compiler/rustc_parse/src/parser/expr.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,7 @@ impl<'a> Parser<'a> {
16031603
self.sess.gated_spans.gate(sym::async_closure, span);
16041604
}
16051605

1606-
let capture_clause = self.parse_capture_clause();
1606+
let capture_clause = self.parse_capture_clause()?;
16071607
let decl = self.parse_fn_block_decl()?;
16081608
let decl_hi = self.prev_token.span;
16091609
let body = match decl.output {
@@ -1626,8 +1626,18 @@ impl<'a> Parser<'a> {
16261626
}
16271627

16281628
/// Parses an optional `move` prefix to a closure-like construct.
1629-
fn parse_capture_clause(&mut self) -> CaptureBy {
1630-
if self.eat_keyword(kw::Move) { CaptureBy::Value } else { CaptureBy::Ref }
1629+
fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
1630+
if self.eat_keyword(kw::Move) {
1631+
// Check for `move async` and recover
1632+
if self.check_keyword(kw::Async) {
1633+
let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo);
1634+
Err(self.incorrect_move_async_order_found(move_async_span))
1635+
} else {
1636+
Ok(CaptureBy::Value)
1637+
}
1638+
} else {
1639+
Ok(CaptureBy::Ref)
1640+
}
16311641
}
16321642

16331643
/// Parses the `|arg, arg|` header of a closure.
@@ -2018,7 +2028,7 @@ impl<'a> Parser<'a> {
20182028
fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
20192029
let lo = self.token.span;
20202030
self.expect_keyword(kw::Async)?;
2021-
let capture_clause = self.parse_capture_clause();
2031+
let capture_clause = self.parse_capture_clause()?;
20222032
let (iattrs, body) = self.parse_inner_attrs_and_block()?;
20232033
attrs.extend(iattrs);
20242034
let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
// edition:2018
3+
4+
// Regression test for issue 79694
5+
6+
fn main() {
7+
let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
// edition:2018
3+
4+
// Regression test for issue 79694
5+
6+
fn main() {
7+
let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: the order of `move` and `async` is incorrect
2+
--> $DIR/incorrect-move-async-order-issue-79694.rs:7:13
3+
|
4+
LL | let _ = move async { };
5+
| ^^^^^^^^^^
6+
|
7+
help: try switching the order
8+
|
9+
LL | let _ = async move { };
10+
| ^^^^^^^^^^
11+
12+
error: aborting due to previous error
13+

0 commit comments

Comments
 (0)