parser: more friendly hints for handling async move in the 2015 edition

This commit is contained in:
bohan 2023-07-30 15:49:33 +08:00
parent d9feb02e8d
commit 8e32dade71
5 changed files with 32 additions and 4 deletions

View File

@ -23,6 +23,8 @@ parse_async_block_in_2015 = `async` blocks are only allowed in Rust 2018 or late
parse_async_fn_in_2015 = `async fn` is not permitted in Rust 2015
.label = to use `async fn`, switch to Rust 2018 or later
parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 2018 or later
parse_async_move_order_incorrect = the order of `move` and `async` is incorrect
.suggestion = try switching the order

View File

@ -1434,6 +1434,13 @@ pub(crate) struct AsyncBlockIn2015 {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_async_move_block_in_2015)]
pub(crate) struct AsyncMoveBlockIn2015 {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_self_argument_pointer)]
pub(crate) struct SelfArgumentPointer {

View File

@ -4,10 +4,11 @@
TokenExpectType, TokenType,
};
use crate::errors::{
AmbiguousPlus, AttributeOnParamType, BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi,
ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg,
ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything,
DocCommentOnParamType, DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
AmbiguousPlus, AsyncMoveBlockIn2015, AttributeOnParamType, BadQPathStage2, BadTypePlus,
BadTypePlusSub, ColonAsSemi, ComparisonOperatorsCannotBeChained,
ComparisonOperatorsCannotBeChainedSugg, ConstGenericWithoutBraces,
ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything, DocCommentOnParamType,
DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg,
HelpIdentifierStartsWithNumber, InInTypo, IncorrectAwait, IncorrectSemicolon,
IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg,
@ -573,6 +574,12 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
return Err(self.sess.create_err(UseEqInstead { span: self.token.span }));
}
if self.token.is_keyword(kw::Move) && self.prev_token.is_keyword(kw::Async) {
// The 2015 edition is in use because parsing of `async move` has failed.
let span = self.prev_token.span.to(self.token.span);
return Err(self.sess.create_err(AsyncMoveBlockIn2015 { span }));
}
let expect = tokens_to_string(&expected);
let actual = super::token_descr(&self.token);
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {

View File

@ -0,0 +1,4 @@
fn main() {
async move {};
//~^ ERROR `async move` blocks are only allowed in Rust 2018 or later
}

View File

@ -0,0 +1,8 @@
error: `async move` blocks are only allowed in Rust 2018 or later
--> $DIR/issue-114219.rs:2:5
|
LL | async move {};
| ^^^^^^^^^^
error: aborting due to previous error