Rollup merge of #80160 - diondokter:move_async_fix, r=davidtwco
Implemented a compiler diagnostic for move async mistake Fixes #79694 First time contributing, so I hope I'm doing everything right. (If not, please correct me!) This code performs a check when a move capture clause is parsed. The check is to detect if the user has reversed the async move keywords and to provide a diagnostic with a suggestion to fix it. Checked code: ```rust fn main() { move async { }; } ``` Previous output: ```txt PS C:\Repos\move_async_test> cargo build Compiling move_async_test v0.1.0 (C:\Repos\move_async_test) error: expected one of `|` or `||`, found keyword `async` --> src\main.rs:2:10 | 2 | move async { }; | ^^^^^ expected one of `|` or `||` error: aborting due to previous error error: could not compile `move_async_test` ``` New output: ```txt PS C:\Repos\move_async_test> cargo +dev build Compiling move_async_test v0.1.0 (C:\Repos\move_async_test) error: the order of `move` and `async` is incorrect --> src\main.rs:2:13 | 2 | let _ = move async { }; | ^^^^^^^^^^ | help: try switching the order | 2 | let _ = async move { }; | ^^^^^^^^^^ error: aborting due to previous error error: could not compile `move_async_test` ``` Is there a file/module where these kind of things are tested? Would love some feedback 😄
This commit is contained in:
commit
299c2fc695
@ -1912,4 +1912,22 @@ impl<'a> Parser<'a> {
|
||||
*self = snapshot;
|
||||
Err(err)
|
||||
}
|
||||
|
||||
/// Get the diagnostics for the cases where `move async` is found.
|
||||
///
|
||||
/// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword
|
||||
pub(super) fn incorrect_move_async_order_found(
|
||||
&self,
|
||||
move_async_span: Span,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
let mut err =
|
||||
self.struct_span_err(move_async_span, "the order of `move` and `async` is incorrect");
|
||||
err.span_suggestion_verbose(
|
||||
move_async_span,
|
||||
"try switching the order",
|
||||
"async move".to_owned(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err
|
||||
}
|
||||
}
|
||||
|
@ -1603,7 +1603,7 @@ impl<'a> Parser<'a> {
|
||||
self.sess.gated_spans.gate(sym::async_closure, span);
|
||||
}
|
||||
|
||||
let capture_clause = self.parse_capture_clause();
|
||||
let capture_clause = self.parse_capture_clause()?;
|
||||
let decl = self.parse_fn_block_decl()?;
|
||||
let decl_hi = self.prev_token.span;
|
||||
let body = match decl.output {
|
||||
@ -1626,8 +1626,18 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parses an optional `move` prefix to a closure-like construct.
|
||||
fn parse_capture_clause(&mut self) -> CaptureBy {
|
||||
if self.eat_keyword(kw::Move) { CaptureBy::Value } else { CaptureBy::Ref }
|
||||
fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
|
||||
if self.eat_keyword(kw::Move) {
|
||||
// Check for `move async` and recover
|
||||
if self.check_keyword(kw::Async) {
|
||||
let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo);
|
||||
Err(self.incorrect_move_async_order_found(move_async_span))
|
||||
} else {
|
||||
Ok(CaptureBy::Value)
|
||||
}
|
||||
} else {
|
||||
Ok(CaptureBy::Ref)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the `|arg, arg|` header of a closure.
|
||||
@ -2019,7 +2029,7 @@ impl<'a> Parser<'a> {
|
||||
fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
|
||||
let lo = self.token.span;
|
||||
self.expect_keyword(kw::Async)?;
|
||||
let capture_clause = self.parse_capture_clause();
|
||||
let capture_clause = self.parse_capture_clause()?;
|
||||
let (iattrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
attrs.extend(iattrs);
|
||||
let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);
|
||||
|
@ -0,0 +1,8 @@
|
||||
// run-rustfix
|
||||
// edition:2018
|
||||
|
||||
// Regression test for issue 79694
|
||||
|
||||
fn main() {
|
||||
let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// run-rustfix
|
||||
// edition:2018
|
||||
|
||||
// Regression test for issue 79694
|
||||
|
||||
fn main() {
|
||||
let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
error: the order of `move` and `async` is incorrect
|
||||
--> $DIR/incorrect-move-async-order-issue-79694.rs:7:13
|
||||
|
|
||||
LL | let _ = move async { };
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: try switching the order
|
||||
|
|
||||
LL | let _ = async move { };
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user