Unsupport the await!(..) macro.
This commit is contained in:
parent
4eeaaa722d
commit
758931948f
9 changed files with 42 additions and 72 deletions
|
@ -4685,7 +4685,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ExprKind::Await(_origin, ref expr) => self.lower_await(e.span, expr),
|
ExprKind::Await(ref expr) => self.lower_await(e.span, expr),
|
||||||
ExprKind::Closure(
|
ExprKind::Closure(
|
||||||
capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
|
capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -1178,7 +1178,7 @@ pub enum ExprKind {
|
||||||
/// preexisting defs.
|
/// preexisting defs.
|
||||||
Async(CaptureBy, NodeId, P<Block>),
|
Async(CaptureBy, NodeId, P<Block>),
|
||||||
/// An await expression (`my_future.await`).
|
/// An await expression (`my_future.await`).
|
||||||
Await(AwaitOrigin, P<Expr>),
|
Await(P<Expr>),
|
||||||
|
|
||||||
/// A try block (`try { ... }`).
|
/// A try block (`try { ... }`).
|
||||||
TryBlock(P<Block>),
|
TryBlock(P<Block>),
|
||||||
|
|
|
@ -468,10 +468,6 @@ declare_features! (
|
||||||
// Allows async and await syntax.
|
// Allows async and await syntax.
|
||||||
(active, async_await, "1.28.0", Some(50547), None),
|
(active, async_await, "1.28.0", Some(50547), None),
|
||||||
|
|
||||||
// Allows await! macro-like syntax.
|
|
||||||
// This will likely be removed prior to stabilization of async/await.
|
|
||||||
(active, await_macro, "1.28.0", Some(50547), None),
|
|
||||||
|
|
||||||
// Allows reinterpretation of the bits of a value of one type as another type during const eval.
|
// Allows reinterpretation of the bits of a value of one type as another type during const eval.
|
||||||
(active, const_transmute, "1.29.0", Some(53605), None),
|
(active, const_transmute, "1.29.0", Some(53605), None),
|
||||||
|
|
||||||
|
@ -627,6 +623,8 @@ declare_features! (
|
||||||
(removed, quote, "1.33.0", Some(29601), None, None),
|
(removed, quote, "1.33.0", Some(29601), None, None),
|
||||||
// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
|
// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
|
||||||
(removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
|
(removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
|
||||||
|
(removed, await_macro, "1.37.0", Some(50547), None,
|
||||||
|
Some("subsumed by `.await` syntax")),
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// feature-group-end: removed features
|
// feature-group-end: removed features
|
||||||
|
@ -2109,19 +2107,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
ast::ExprKind::Async(..) => {
|
ast::ExprKind::Async(..) => {
|
||||||
gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
|
gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
|
||||||
}
|
}
|
||||||
ast::ExprKind::Await(origin, _) => {
|
ast::ExprKind::Await(_) => {
|
||||||
match origin {
|
gate_feature_post!(&self, async_await, e.span, "async/await is unstable");
|
||||||
ast::AwaitOrigin::FieldLike =>
|
|
||||||
gate_feature_post!(&self, async_await, e.span, "async/await is unstable"),
|
|
||||||
ast::AwaitOrigin::MacroLike =>
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
await_macro,
|
|
||||||
e.span,
|
|
||||||
"`await!(<expr>)` macro syntax is unstable, and will soon be removed \
|
|
||||||
in favor of `<expr>.await` syntax."
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1139,7 +1139,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
|
||||||
vis.visit_id(node_id);
|
vis.visit_id(node_id);
|
||||||
vis.visit_block(body);
|
vis.visit_block(body);
|
||||||
}
|
}
|
||||||
ExprKind::Await(_origin, expr) => vis.visit_expr(expr),
|
ExprKind::Await(expr) => vis.visit_expr(expr),
|
||||||
ExprKind::Assign(el, er) => {
|
ExprKind::Assign(el, er) => {
|
||||||
vis.visit_expr(el);
|
vis.visit_expr(el);
|
||||||
vis.visit_expr(er);
|
vis.visit_expr(er);
|
||||||
|
|
|
@ -869,13 +869,23 @@ impl<'a> Parser<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)`
|
/// Consume alternative await syntaxes like `await!(<expr>)`, `await <expr>`,
|
||||||
/// and `await { <expr> }`.
|
/// `await? <expr>`, `await(<expr>)`, and `await { <expr> }`.
|
||||||
crate fn parse_incorrect_await_syntax(
|
crate fn parse_incorrect_await_syntax(
|
||||||
&mut self,
|
&mut self,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
await_sp: Span,
|
await_sp: Span,
|
||||||
) -> PResult<'a, (Span, ExprKind)> {
|
) -> PResult<'a, (Span, ExprKind)> {
|
||||||
|
if self.token == token::Not {
|
||||||
|
// Handle `await!(<expr>)`.
|
||||||
|
self.expect(&token::Not)?;
|
||||||
|
self.expect(&token::OpenDelim(token::Paren))?;
|
||||||
|
let expr = self.parse_expr()?;
|
||||||
|
self.expect(&token::CloseDelim(token::Paren))?;
|
||||||
|
let sp = self.error_on_incorrect_await(lo, self.prev_span, &expr, false);
|
||||||
|
return Ok((sp, ExprKind::Await(expr)))
|
||||||
|
}
|
||||||
|
|
||||||
let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
|
let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
|
||||||
let expr = if self.token == token::OpenDelim(token::Brace) {
|
let expr = if self.token == token::OpenDelim(token::Brace) {
|
||||||
// Handle `await { <expr> }`.
|
// Handle `await { <expr> }`.
|
||||||
|
@ -893,10 +903,15 @@ impl<'a> Parser<'a> {
|
||||||
err.span_label(await_sp, "while parsing this incorrect await expression");
|
err.span_label(await_sp, "while parsing this incorrect await expression");
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
let sp = self.error_on_incorrect_await(lo, expr.span, &expr, is_question);
|
||||||
|
Ok((sp, ExprKind::Await(expr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_on_incorrect_await(&self, lo: Span, hi: Span, expr: &Expr, is_question: bool) -> Span {
|
||||||
let expr_str = self.span_to_snippet(expr.span)
|
let expr_str = self.span_to_snippet(expr.span)
|
||||||
.unwrap_or_else(|_| pprust::expr_to_string(&expr));
|
.unwrap_or_else(|_| pprust::expr_to_string(&expr));
|
||||||
let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" });
|
let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" });
|
||||||
let sp = lo.to(expr.span);
|
let sp = lo.to(hi);
|
||||||
let app = match expr.node {
|
let app = match expr.node {
|
||||||
ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
|
ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
|
||||||
_ => Applicability::MachineApplicable,
|
_ => Applicability::MachineApplicable,
|
||||||
|
@ -904,7 +919,7 @@ impl<'a> Parser<'a> {
|
||||||
self.struct_span_err(sp, "incorrect use of `await`")
|
self.struct_span_err(sp, "incorrect use of `await`")
|
||||||
.span_suggestion(sp, "`await` is a postfix operation", suggestion, app)
|
.span_suggestion(sp, "`await` is a postfix operation", suggestion, app)
|
||||||
.emit();
|
.emit();
|
||||||
Ok((sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr)))
|
sp
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If encountering `future.await()`, consume and emit error.
|
/// If encountering `future.await()`, consume and emit error.
|
||||||
|
|
|
@ -2234,7 +2234,7 @@ impl<'a> Parser<'a> {
|
||||||
} else if self.eat_keyword(kw::Let) {
|
} else if self.eat_keyword(kw::Let) {
|
||||||
return self.parse_let_expr(attrs);
|
return self.parse_let_expr(attrs);
|
||||||
} else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
|
} else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
|
||||||
let (await_hi, e_kind) = self.parse_await_macro_or_alt(lo, self.prev_span)?;
|
let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?;
|
||||||
hi = await_hi;
|
hi = await_hi;
|
||||||
ex = e_kind;
|
ex = e_kind;
|
||||||
} else if self.token.is_path_start() {
|
} else if self.token.is_path_start() {
|
||||||
|
@ -2282,31 +2282,6 @@ impl<'a> Parser<'a> {
|
||||||
self.maybe_recover_from_bad_qpath(expr, true)
|
self.maybe_recover_from_bad_qpath(expr, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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)> {
|
|
||||||
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
|
|
||||||
})?;
|
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
|
||||||
Ok((self.prev_span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr)))
|
|
||||||
} else { // Handle `await <expr>`.
|
|
||||||
self.parse_incorrect_await_syntax(lo, await_sp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn maybe_parse_struct_expr(
|
fn maybe_parse_struct_expr(
|
||||||
&mut self,
|
&mut self,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
|
@ -2509,18 +2484,19 @@ impl<'a> Parser<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assuming we have just parsed `.`, continue parsing into an expression.
|
fn mk_await_expr(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
|
||||||
|
let span = lo.to(self.prev_span);
|
||||||
|
let await_expr = self.mk_expr(span, ExprKind::Await(self_arg), ThinVec::new());
|
||||||
|
self.recover_from_await_method_call();
|
||||||
|
Ok(await_expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assuming we have just parsed `.`, continue parsing into an expression.
|
||||||
fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
|
fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
|
||||||
if self.token.span.rust_2018() && self.eat_keyword(kw::Await) {
|
if self.token.span.rust_2018() && self.eat_keyword(kw::Await) {
|
||||||
let span = lo.to(self.prev_span);
|
return self.mk_await_expr(self_arg, lo);
|
||||||
let await_expr = self.mk_expr(
|
|
||||||
span,
|
|
||||||
ExprKind::Await(ast::AwaitOrigin::FieldLike, self_arg),
|
|
||||||
ThinVec::new(),
|
|
||||||
);
|
|
||||||
self.recover_from_await_method_call();
|
|
||||||
return Ok(await_expr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let segment = self.parse_path_segment(PathStyle::Expr)?;
|
let segment = self.parse_path_segment(PathStyle::Expr)?;
|
||||||
self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren));
|
self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren));
|
||||||
|
|
||||||
|
|
|
@ -2120,18 +2120,10 @@ impl<'a> State<'a> {
|
||||||
self.ibox(0);
|
self.ibox(0);
|
||||||
self.print_block_with_attrs(blk, attrs);
|
self.print_block_with_attrs(blk, attrs);
|
||||||
}
|
}
|
||||||
ast::ExprKind::Await(origin, ref expr) => {
|
ast::ExprKind::Await(ref expr) => {
|
||||||
match origin {
|
|
||||||
ast::AwaitOrigin::MacroLike => {
|
|
||||||
self.s.word("await!");
|
|
||||||
self.print_expr_maybe_paren(expr, parser::PREC_FORCE_PAREN);
|
|
||||||
}
|
|
||||||
ast::AwaitOrigin::FieldLike => {
|
|
||||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||||
self.s.word(".await");
|
self.s.word(".await");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::ExprKind::Assign(ref lhs, ref rhs) => {
|
ast::ExprKind::Assign(ref lhs, ref rhs) => {
|
||||||
let prec = AssocOp::Assign.precedence() as i8;
|
let prec = AssocOp::Assign.precedence() as i8;
|
||||||
self.print_expr_maybe_paren(lhs, prec + 1);
|
self.print_expr_maybe_paren(lhs, prec + 1);
|
||||||
|
|
|
@ -382,7 +382,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
|
||||||
// X { y: 1 } + X { y: 2 }
|
// X { y: 1 } + X { y: 2 }
|
||||||
contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
|
contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
|
||||||
}
|
}
|
||||||
ast::ExprKind::Await(_, ref x) |
|
ast::ExprKind::Await(ref x) |
|
||||||
ast::ExprKind::Unary(_, ref x) |
|
ast::ExprKind::Unary(_, ref x) |
|
||||||
ast::ExprKind::Cast(ref x, _) |
|
ast::ExprKind::Cast(ref x, _) |
|
||||||
ast::ExprKind::Type(ref x, _) |
|
ast::ExprKind::Type(ref x, _) |
|
||||||
|
|
|
@ -757,7 +757,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||||
ExprKind::Async(_, _, ref body) => {
|
ExprKind::Async(_, _, ref body) => {
|
||||||
visitor.visit_block(body);
|
visitor.visit_block(body);
|
||||||
}
|
}
|
||||||
ExprKind::Await(_, ref expr) => visitor.visit_expr(expr),
|
ExprKind::Await(ref expr) => visitor.visit_expr(expr),
|
||||||
ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
|
ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
|
||||||
visitor.visit_expr(left_hand_expression);
|
visitor.visit_expr(left_hand_expression);
|
||||||
visitor.visit_expr(right_hand_expression);
|
visitor.visit_expr(right_hand_expression);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue