Skip to content

Commit

Permalink
Rollup merge of rust-lang#62293 - Centril:remove-await-macro, r=cramertj
Browse files Browse the repository at this point in the history
Unsupport the `await!(future)` macro

Unsupport the `await!(future)` "macro" and recognize it in error recovery instead.

The `future.await` syntax has been on nightly since 2019-05-08.
This was 55 days ago which is 1.31 releases ago.

Closes rust-lang#60610.

r? @cramertj
  • Loading branch information
Centril authored Jul 30, 2019
2 parents f690098 + b21f0a3 commit d8280fa
Show file tree
Hide file tree
Showing 21 changed files with 164 additions and 353 deletions.
10 changes: 5 additions & 5 deletions src/librustc/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2088,11 +2088,11 @@ generator can be constructed.
Erroneous code example:
```edition2018,compile-fail,E0698
#![feature(futures_api, async_await, await_macro)]
#![feature(async_await)]
async fn bar<T>() -> () {}
async fn foo() {
await!(bar()); // error: cannot infer type for `T`
bar().await; // error: cannot infer type for `T`
}
```
Expand All @@ -2101,12 +2101,12 @@ To fix this you must bind `T` to a concrete type such as `String`
so that a generator can then be constructed:
```edition2018
#![feature(futures_api, async_await, await_macro)]
#![feature(async_await)]
async fn bar<T>() -> () {}
async fn foo() {
await!(bar::<String>());
// ^^^^^^^^ specify type explicitly
bar::<String>().await;
// ^^^^^^^^ specify type explicitly
}
```
"##,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
) => {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1178,7 +1178,7 @@ pub enum ExprKind {
/// preexisting defs.
Async(CaptureBy, NodeId, P<Block>),
/// An await expression (`my_future.await`).
Await(AwaitOrigin, P<Expr>),
Await(P<Expr>),

/// A try block (`try { ... }`).
TryBlock(P<Block>),
Expand Down
21 changes: 4 additions & 17 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,10 +468,6 @@ declare_features! (
// Allows async and await syntax.
(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.
(active, const_transmute, "1.29.0", Some(53605), None),

Expand Down Expand Up @@ -627,6 +623,8 @@ declare_features! (
(removed, quote, "1.33.0", Some(29601), None, None),
// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
(removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
(removed, await_macro, "1.38.0", Some(50547), None,
Some("subsumed by `.await` syntax")),

// -------------------------------------------------------------------------
// feature-group-end: removed features
Expand Down Expand Up @@ -2109,19 +2107,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::ExprKind::Async(..) => {
gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
}
ast::ExprKind::Await(origin, _) => {
match origin {
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."
),
}
ast::ExprKind::Await(_) => {
gate_feature_post!(&self, async_await, e.span, "async/await is unstable");
}
_ => {}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_block(body);
}
ExprKind::Await(_origin, expr) => vis.visit_expr(expr),
ExprKind::Await(expr) => vis.visit_expr(expr),
ExprKind::Assign(el, er) => {
vis.visit_expr(el);
vis.visit_expr(er);
Expand Down
23 changes: 19 additions & 4 deletions src/libsyntax/parse/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,13 +869,23 @@ impl<'a> Parser<'a> {
Ok(())
}

/// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)`
/// and `await { <expr> }`.
/// Consume alternative await syntaxes like `await!(<expr>)`, `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)> {
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 expr = if self.token == token::OpenDelim(token::Brace) {
// Handle `await { <expr> }`.
Expand All @@ -893,18 +903,23 @@ impl<'a> Parser<'a> {
err.span_label(await_sp, "while parsing this incorrect await expression");
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)
.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 sp = lo.to(hi);
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)))
sp
}

/// If encountering `future.await()`, consume and emit error.
Expand Down
46 changes: 11 additions & 35 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2234,7 +2234,7 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(kw::Let) {
return self.parse_let_expr(attrs);
} 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;
ex = e_kind;
} else if self.token.is_path_start() {
Expand Down Expand Up @@ -2282,31 +2282,6 @@ impl<'a> Parser<'a> {
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(
&mut self,
lo: Span,
Expand Down Expand Up @@ -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>> {
if self.token.span.rust_2018() && self.eat_keyword(kw::Await) {
let span = lo.to(self.prev_span);
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);
return self.mk_await_expr(self_arg, lo);
}

let segment = self.parse_path_segment(PathStyle::Expr)?;
self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren));

Expand Down
14 changes: 3 additions & 11 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2120,17 +2120,9 @@ impl<'a> State<'a> {
self.ibox(0);
self.print_block_with_attrs(blk, attrs);
}
ast::ExprKind::Await(origin, 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.s.word(".await");
}
}
ast::ExprKind::Await(ref expr) => {
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
self.s.word(".await");
}
ast::ExprKind::Assign(ref lhs, ref rhs) => {
let prec = AssocOp::Assign.precedence() as i8;
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/util/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
// X { y: 1 } + X { y: 2 }
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::Cast(ref x, _) |
ast::ExprKind::Type(ref x, _) |
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
ExprKind::Async(_, _, ref 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) => {
visitor.visit_expr(left_hand_expression);
visitor.visit_expr(right_hand_expression);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(async_await, await_macro)]
#![feature(async_await)]
#![allow(non_camel_case_types)]
#![deny(keyword_idents)]

Expand Down Expand Up @@ -29,6 +29,9 @@ macro_rules! await {
}

fn main() {
await!(); //~ ERROR `await` is a keyword in the 2018 edition
//~^ WARN this was previously accepted by the compiler

match await { await => {} } //~ ERROR `await` is a keyword in the 2018 edition
//~^ ERROR `await` is a keyword in the 2018 edition
//~^^ WARN this was previously accepted by the compiler
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:6:13
--> $DIR/2015-edition-error-various-positions.rs:6:13
|
LL | pub mod await {
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
|
note: lint level defined here
--> $DIR/2015-edition-error-in-non-macro-position.rs:3:9
--> $DIR/2015-edition-error-various-positions.rs:3:9
|
LL | #![deny(keyword_idents)]
| ^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:8:20
--> $DIR/2015-edition-error-various-positions.rs:8:20
|
LL | pub struct await;
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
Expand All @@ -22,7 +22,7 @@ LL | pub struct await;
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:12:16
--> $DIR/2015-edition-error-various-positions.rs:12:16
|
LL | use outer_mod::await::await;
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
Expand All @@ -31,7 +31,7 @@ LL | use outer_mod::await::await;
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:12:23
--> $DIR/2015-edition-error-various-positions.rs:12:23
|
LL | use outer_mod::await::await;
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
Expand All @@ -40,7 +40,7 @@ LL | use outer_mod::await::await;
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:17:14
--> $DIR/2015-edition-error-various-positions.rs:17:14
|
LL | struct Foo { await: () }
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
Expand All @@ -49,7 +49,7 @@ LL | struct Foo { await: () }
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:21:15
--> $DIR/2015-edition-error-various-positions.rs:21:15
|
LL | impl Foo { fn await() {} }
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
Expand All @@ -58,7 +58,7 @@ LL | impl Foo { fn await() {} }
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:25:14
--> $DIR/2015-edition-error-various-positions.rs:25:14
|
LL | macro_rules! await {
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
Expand All @@ -67,7 +67,16 @@ LL | macro_rules! await {
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:32:11
--> $DIR/2015-edition-error-various-positions.rs:32:5
|
LL | await!();
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-various-positions.rs:35:11
|
LL | match await { await => {} }
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
Expand All @@ -76,13 +85,13 @@ LL | match await { await => {} }
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: `await` is a keyword in the 2018 edition
--> $DIR/2015-edition-error-in-non-macro-position.rs:32:19
--> $DIR/2015-edition-error-various-positions.rs:35:19
|
LL | match await { await => {} }
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

error: aborting due to 9 previous errors
error: aborting due to 10 previous errors

6 changes: 5 additions & 1 deletion src/test/ui/async-await/await-keyword/2018-edition-error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ mod outer_mod {
use self::outer_mod::await::await; //~ ERROR expected identifier
//~^ ERROR expected identifier, found reserved keyword `await`

fn main() {}
macro_rules! await { () => {}; } //~ ERROR expected identifier, found reserved keyword `await`

fn main() {
await!(); //~ ERROR expected expression, found `)`
}
Loading

0 comments on commit d8280fa

Please sign in to comment.