Review comments
- Change wording of suggestion - Move recovery logic to `diagnostics.rs` - Reduce ammount of code duplication
This commit is contained in:
parent
0183a575f6
commit
b9d6fe3ae9
@ -1,5 +1,5 @@
|
||||
use crate::ast;
|
||||
use crate::ast::{Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind};
|
||||
use crate::ast::{BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind};
|
||||
use crate::parse::parser::PathStyle;
|
||||
use crate::parse::token;
|
||||
use crate::parse::PResult;
|
||||
@ -223,4 +223,42 @@ impl<'a> Parser<'a> {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)`
|
||||
/// and `await { <expr> }`.
|
||||
crate fn parse_incorrect_await_syntax(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
await_sp: Span,
|
||||
) -> PResult<'a, (Span, ExprKind)> {
|
||||
let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
|
||||
let expr = if self.token == token::OpenDelim(token::Brace) {
|
||||
// Handle `await { <expr> }`.
|
||||
// This needs to be handled separatedly from the next arm to avoid
|
||||
// interpreting `await { <expr> }?` as `<expr>?.await`.
|
||||
self.parse_block_expr(
|
||||
None,
|
||||
self.span,
|
||||
BlockCheckMode::Default,
|
||||
ThinVec::new(),
|
||||
)
|
||||
} else {
|
||||
self.parse_expr()
|
||||
}.map_err(|mut err| {
|
||||
err.span_label(await_sp, "while parsing this incorrect await expression");
|
||||
err
|
||||
})?;
|
||||
let expr_str = self.sess.source_map().span_to_snippet(expr.span)
|
||||
.unwrap_or_else(|_| pprust::expr_to_string(&expr));
|
||||
let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" });
|
||||
let sp = lo.to(expr.span);
|
||||
let app = match expr.node {
|
||||
ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
|
||||
_ => Applicability::MachineApplicable,
|
||||
};
|
||||
self.struct_span_err(sp, "incorrect use of `await`")
|
||||
.span_suggestion(sp, "`await` is a postfix operation", suggestion, app)
|
||||
.emit();
|
||||
Ok((sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr)))
|
||||
}
|
||||
}
|
||||
|
@ -2629,10 +2629,9 @@ impl<'a> Parser<'a> {
|
||||
db.note("variable declaration using `let` is a statement");
|
||||
return Err(db);
|
||||
} else if self.span.rust_2018() && self.eat_keyword(keywords::Await) {
|
||||
let await_sp = self.prev_span;
|
||||
let e = self.parse_async_macro_or_stmt(lo, await_sp)?;
|
||||
hi = e.0;
|
||||
ex = e.1;
|
||||
let (await_hi, e_kind) = self.parse_await_macro_or_alt(lo, self.prev_span)?;
|
||||
hi = await_hi;
|
||||
ex = e_kind;
|
||||
} else if self.token.is_path_start() {
|
||||
let path = self.parse_path(PathStyle::Expr)?;
|
||||
|
||||
@ -2697,97 +2696,29 @@ impl<'a> Parser<'a> {
|
||||
self.maybe_recover_from_bad_qpath(expr, true)
|
||||
}
|
||||
|
||||
fn parse_async_macro_or_stmt(
|
||||
/// Parse `await!(<expr>)` calls, or alternatively recover from incorrect but reasonable
|
||||
/// alternative syntaxes `await <expr>`, `await? <expr>`, `await(<expr>)` and
|
||||
/// `await { <expr> }`.
|
||||
fn parse_await_macro_or_alt(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
await_sp: Span,
|
||||
) -> PResult<'a, (Span, ExprKind)> {
|
||||
Ok(match self.token {
|
||||
token::Not => {
|
||||
// Handle correct `await!(<expr>)`
|
||||
if self.token == token::Not {
|
||||
// Handle correct `await!(<expr>)`.
|
||||
// FIXME: make this an error when `await!` is no longer supported
|
||||
// https://github.com/rust-lang/rust/issues/60610
|
||||
self.expect(&token::Not)?;
|
||||
self.expect(&token::OpenDelim(token::Paren))?;
|
||||
let expr = self.parse_expr().map_err(|mut err| {
|
||||
err.span_label(
|
||||
await_sp,
|
||||
"while parsing this await macro call",
|
||||
);
|
||||
err.span_label(await_sp, "while parsing this await macro call");
|
||||
err
|
||||
})?;
|
||||
self.expect(&token::CloseDelim(token::Paren))?;
|
||||
(expr.span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr))
|
||||
Ok((expr.span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr)))
|
||||
} else { // Handle `await <expr>`.
|
||||
self.parse_incorrect_await_syntax(lo, await_sp)
|
||||
}
|
||||
token::Question => {
|
||||
// Handle `await? <expr>`
|
||||
self.bump(); // `?`
|
||||
let expr = self.parse_expr().map_err(|mut err| {
|
||||
err.span_label(
|
||||
await_sp,
|
||||
"while parsing this incorrect await statement",
|
||||
);
|
||||
err
|
||||
})?;
|
||||
let sp = lo.to(expr.span);
|
||||
let expr_str = self.sess.source_map().span_to_snippet(expr.span)
|
||||
.unwrap_or_else(|_| pprust::expr_to_string(&expr));
|
||||
let expr = self.mk_expr(
|
||||
sp,
|
||||
ExprKind::Await(ast::AwaitOrigin::FieldLike, expr),
|
||||
ThinVec::new(),
|
||||
);
|
||||
let mut err = self.struct_span_err(
|
||||
sp,
|
||||
"incorrect use of `await`",
|
||||
);
|
||||
err.span_suggestion(
|
||||
sp,
|
||||
"`await` is not a statement",
|
||||
format!("{}.await?", expr_str),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
(sp, ExprKind::Try(expr))
|
||||
}
|
||||
ref t => {
|
||||
// Handle `await <expr>`
|
||||
let expr = if t == &token::OpenDelim(token::Brace) {
|
||||
// Handle `await { <expr> }`
|
||||
// this needs to be handled separatedly from the next arm to avoid
|
||||
// interpreting `await { <expr> }?` as `<expr>?.await`
|
||||
self.parse_block_expr(
|
||||
None,
|
||||
self.span,
|
||||
BlockCheckMode::Default,
|
||||
ThinVec::new(),
|
||||
)
|
||||
} else {
|
||||
self.parse_expr()
|
||||
}.map_err(|mut err| {
|
||||
err.span_label(
|
||||
await_sp,
|
||||
"while parsing this incorrect await statement",
|
||||
);
|
||||
err
|
||||
})?;
|
||||
let expr_str = self.sess.source_map().span_to_snippet(expr.span)
|
||||
.unwrap_or_else(|_| pprust::expr_to_string(&expr));
|
||||
let sp = lo.to(expr.span);
|
||||
let mut err = self.struct_span_err(
|
||||
sp,
|
||||
"incorrect use of `await`",
|
||||
);
|
||||
err.span_suggestion(
|
||||
sp,
|
||||
"`await` is not a statement",
|
||||
format!("{}.await", expr_str),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
(sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn maybe_parse_struct_expr(
|
||||
@ -2938,10 +2869,13 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parses a block or unsafe block.
|
||||
fn parse_block_expr(&mut self, opt_label: Option<Label>,
|
||||
lo: Span, blk_mode: BlockCheckMode,
|
||||
outer_attrs: ThinVec<Attribute>)
|
||||
-> PResult<'a, P<Expr>> {
|
||||
crate fn parse_block_expr(
|
||||
&mut self,
|
||||
opt_label: Option<Label>,
|
||||
lo: Span,
|
||||
blk_mode: BlockCheckMode,
|
||||
outer_attrs: ThinVec<Attribute>,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
|
||||
let mut attrs = outer_attrs;
|
||||
|
@ -2,43 +2,43 @@ error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:10:13
|
||||
|
|
||||
LL | let _ = await bar();
|
||||
| ^^^^^^^^^^^ help: `await` is not a statement: `bar().await`
|
||||
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:14:13
|
||||
|
|
||||
LL | let _ = await? bar();
|
||||
| ^^^^^^^^^^^^ help: `await` is not a statement: `bar().await?`
|
||||
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:18:13
|
||||
|
|
||||
LL | let _ = await bar()?;
|
||||
| ^^^^^^^^^^^^ help: `await` is not a statement: `bar()?.await`
|
||||
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:23:13
|
||||
|
|
||||
LL | let _ = await { bar() };
|
||||
| ^^^^^^^^^^^^^^^ help: `await` is not a statement: `{ bar() }.await`
|
||||
| ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:27:13
|
||||
|
|
||||
LL | let _ = await(bar());
|
||||
| ^^^^^^^^^^^^ help: `await` is not a statement: `(bar()).await`
|
||||
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:31:13
|
||||
|
|
||||
LL | let _ = await { bar() }?;
|
||||
| ^^^^^^^^^^^^^^^ help: `await` is not a statement: `{ bar() }.await`
|
||||
| ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:35:14
|
||||
|
|
||||
LL | let _ = (await bar())?;
|
||||
| ^^^^^^^^^^^ help: `await` is not a statement: `bar().await`
|
||||
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:39:24
|
||||
@ -56,25 +56,25 @@ error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:55:13
|
||||
|
|
||||
LL | let _ = await bar();
|
||||
| ^^^^^^^^^^^ help: `await` is not a statement: `bar().await`
|
||||
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:60:13
|
||||
|
|
||||
LL | let _ = await? bar();
|
||||
| ^^^^^^^^^^^^ help: `await` is not a statement: `bar().await?`
|
||||
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:65:13
|
||||
|
|
||||
LL | let _ = await bar()?;
|
||||
| ^^^^^^^^^^^^ help: `await` is not a statement: `bar()?.await`
|
||||
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:70:14
|
||||
|
|
||||
LL | let _ = (await bar())?;
|
||||
| ^^^^^^^^^^^ help: `await` is not a statement: `bar().await`
|
||||
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:75:24
|
||||
@ -94,13 +94,13 @@ error: expected expression, found `=>`
|
||||
LL | match await { await => () }
|
||||
| ----- ^^ expected expression
|
||||
| |
|
||||
| while parsing this incorrect await statement
|
||||
| while parsing this incorrect await expression
|
||||
|
||||
error: incorrect use of `await`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:108:11
|
||||
|
|
||||
LL | match await { await => () }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: `await` is not a statement: `{ await => () }.await`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
|
||||
|
||||
error: expected one of `.`, `?`, `{`, or an operator, found `}`
|
||||
--> $DIR/incorrect-syntax-suggestions.rs:111:1
|
||||
|
Loading…
Reference in New Issue
Block a user