Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsupport the await!(future) macro #62293

Merged
merged 4 commits into from
Jul 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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