diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 1edadbd5bae1a..b3eee7c346489 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -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() -> () {} async fn foo() { - await!(bar()); // error: cannot infer type for `T` + bar().await; // error: cannot infer type for `T` } ``` @@ -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() -> () {} async fn foo() { - await!(bar::()); - // ^^^^^^^^ specify type explicitly + bar::().await; + // ^^^^^^^^ specify type explicitly } ``` "##, diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4ddd7818bb1aa..026c3cc6f95b2 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -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 ) => { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 58a1c4aee9ad9..b633705a65f5d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1178,7 +1178,7 @@ pub enum ExprKind { /// preexisting defs. Async(CaptureBy, NodeId, P), /// An await expression (`my_future.await`). - Await(AwaitOrigin, P), + Await(P), /// A try block (`try { ... }`). TryBlock(P), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 34e4d7d5a1993..d11deeb864542 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -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), @@ -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 @@ -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!()` macro syntax is unstable, and will soon be removed \ - in favor of `.await` syntax." - ), - } + ast::ExprKind::Await(_) => { + gate_feature_post!(&self, async_await, e.span, "async/await is unstable"); } _ => {} } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 43b6bea69d9ed..7b328e817bf8e 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -1139,7 +1139,7 @@ pub fn noop_visit_expr(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); diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index 9eb6aa303b06b..730efb5ef013c 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -869,13 +869,23 @@ impl<'a> Parser<'a> { Ok(()) } - /// Consume alternative await syntaxes like `await `, `await? `, `await()` - /// and `await { }`. + /// Consume alternative await syntaxes like `await!()`, `await `, + /// `await? `, `await()`, and `await { }`. crate fn parse_incorrect_await_syntax( &mut self, lo: Span, await_sp: Span, ) -> PResult<'a, (Span, ExprKind)> { + if self.token == token::Not { + // Handle `await!()`. + 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? `. let expr = if self.token == token::OpenDelim(token::Brace) { // Handle `await { }`. @@ -893,10 +903,15 @@ 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 ?` _ => Applicability::MachineApplicable, @@ -904,7 +919,7 @@ impl<'a> Parser<'a> { 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. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fb5ff7e8f9862..7fda9158b4bdf 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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() { @@ -2282,31 +2282,6 @@ impl<'a> Parser<'a> { self.maybe_recover_from_bad_qpath(expr, true) } - /// Parse `await!()` calls, or alternatively recover from incorrect but reasonable - /// alternative syntaxes `await `, `await? `, `await()` and - /// `await { }`. - 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!()`. - // 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 `. - self.parse_incorrect_await_syntax(lo, await_sp) - } - } - fn maybe_parse_struct_expr( &mut self, 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, lo: Span) -> PResult<'a, P> { + 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, lo: Span) -> PResult<'a, P> { 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)); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c7be0b123023d..88ff6ee907101 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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; diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index 1e52186a106c1..d71358f45c470 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -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, _) | diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 50be8c68f7f8c..5fee8ed81ab3b 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -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); diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs similarity index 89% rename from src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs rename to src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs index c4f3f3edc486e..422a5a6394f8e 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs @@ -1,4 +1,4 @@ -#![feature(async_await, await_macro)] +#![feature(async_await)] #![allow(non_camel_case_types)] #![deny(keyword_idents)] @@ -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 diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr similarity index 78% rename from src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr rename to src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index 067ecd6a5138d..8af0110169ebd 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -1,11 +1,11 @@ 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)] | ^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(keyword_idents)] = note: for more information, see issue #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` @@ -22,7 +22,7 @@ LL | pub struct await; = note: for more information, see issue #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` @@ -31,7 +31,7 @@ LL | use outer_mod::await::await; = note: for more information, see issue #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` @@ -40,7 +40,7 @@ LL | use outer_mod::await::await; = note: for more information, see issue #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` @@ -49,7 +49,7 @@ LL | struct Foo { await: () } = note: for more information, see issue #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` @@ -58,7 +58,7 @@ LL | impl Foo { fn await() {} } = note: for more information, see issue #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` @@ -67,7 +67,16 @@ LL | macro_rules! await { = note: for more information, see issue #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 + +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` @@ -76,7 +85,7 @@ LL | match await { await => {} } = note: for more information, see issue #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` @@ -84,5 +93,5 @@ LL | match await { 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 -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.rs b/src/test/ui/async-await/await-keyword/2018-edition-error.rs index d856869684266..e620c27f9e36d 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error.rs +++ b/src/test/ui/async-await/await-keyword/2018-edition-error.rs @@ -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 `)` +} diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error.stderr index 8afe5c1a36b36..9304928cfde5d 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error.stderr +++ b/src/test/ui/async-await/await-keyword/2018-edition-error.stderr @@ -38,5 +38,21 @@ help: you can escape reserved keywords to use them as identifiers LL | use self::outer_mod::await::r#await; | ^^^^^^^ -error: aborting due to 4 previous errors +error: expected identifier, found reserved keyword `await` + --> $DIR/2018-edition-error.rs:12:14 + | +LL | macro_rules! await { () => {}; } + | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | macro_rules! r#await { () => {}; } + | ^^^^^^^ + +error: expected expression, found `)` + --> $DIR/2018-edition-error.rs:15:12 + | +LL | await!(); + | ^ expected expression + +error: aborting due to 6 previous errors diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs index e1e5bdd3d1b92..25da337c58798 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs @@ -104,6 +104,31 @@ fn foo25() -> Result<(), ()> { foo() } +async fn foo26() -> Result<(), ()> { + let _ = await!(bar()); //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo27() -> Result<(), ()> { + let _ = await!(bar())?; //~ ERROR incorrect use of `await` + Ok(()) +} +fn foo28() -> Result<(), ()> { + fn foo() -> Result<(), ()> { + let _ = await!(bar())?; //~ ERROR incorrect use of `await` + //~^ ERROR `await` is only allowed inside `async` functions + Ok(()) + } + foo() +} +fn foo29() -> Result<(), ()> { + let foo = || { + let _ = await!(bar())?; //~ ERROR incorrect use of `await` + //~^ ERROR `await` is only allowed inside `async` functions + Ok(()) + }; + foo() +} + fn main() { match await { await => () } //~^ ERROR expected expression, found `=>` diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr index 380da4448ad32..db86d3d5d03ba 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr @@ -88,8 +88,32 @@ error: incorrect use of `await` LL | let _ = bar().await()?; | ^^ help: `await` is not a method call, remove the parentheses +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:108:13 + | +LL | let _ = await!(bar()); + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:112:13 + | +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:117:17 + | +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:125:17 + | +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + error: expected expression, found `=>` - --> $DIR/incorrect-syntax-suggestions.rs:108:25 + --> $DIR/incorrect-syntax-suggestions.rs:133:25 | LL | match await { await => () } | ----- ^^ expected expression @@ -97,13 +121,13 @@ LL | match await { await => () } | while parsing this incorrect await expression error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:108:11 + --> $DIR/incorrect-syntax-suggestions.rs:133:11 | LL | match 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 + --> $DIR/incorrect-syntax-suggestions.rs:136:1 | LL | match await { await => () } | ----- - expected one of `.`, `?`, `{`, or an operator here @@ -193,6 +217,22 @@ LL | let foo = || { LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:117:17 + | +LL | fn foo() -> Result<(), ()> { + | --- this is not `async` +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:125:17 + | +LL | let foo = || { + | -- this is not `async` +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/incorrect-syntax-suggestions.rs:18:19 | @@ -202,6 +242,6 @@ LL | let _ = await bar()?; = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future` = note: required by `std::ops::Try::into_result` -error: aborting due to 29 previous errors +error: aborting due to 35 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/await-keyword/post_expansion_error.stderr b/src/test/ui/async-await/await-keyword/post_expansion_error.stderr index 4e525974c2c6f..0996c38b3b6c6 100644 --- a/src/test/ui/async-await/await-keyword/post_expansion_error.stderr +++ b/src/test/ui/async-await/await-keyword/post_expansion_error.stderr @@ -2,9 +2,7 @@ error: expected expression, found `)` --> $DIR/post_expansion_error.rs:8:12 | LL | await!() - | ----- ^ expected expression - | | - | while parsing this await macro call + | ^ expected expression error: aborting due to previous error diff --git a/src/test/ui/async-await/await-macro.rs b/src/test/ui/async-await/await-macro.rs deleted file mode 100644 index b9cd3903513a4..0000000000000 --- a/src/test/ui/async-await/await-macro.rs +++ /dev/null @@ -1,230 +0,0 @@ -// run-pass - -// edition:2018 -// aux-build:arc_wake.rs - -#![feature(async_await, async_closure, await_macro)] - -extern crate arc_wake; - -use std::pin::Pin; -use std::future::Future; -use std::sync::{ - Arc, - atomic::{self, AtomicUsize}, -}; -use std::task::{Context, Poll}; -use arc_wake::ArcWake; - -struct Counter { - wakes: AtomicUsize, -} - -impl ArcWake for Counter { - fn wake(self: Arc) { - Self::wake_by_ref(&self) - } - fn wake_by_ref(arc_self: &Arc) { - arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); - } -} - -struct WakeOnceThenComplete(bool); - -fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } - -impl Future for WakeOnceThenComplete { - type Output = (); - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { - if self.0 { - Poll::Ready(()) - } else { - cx.waker().wake_by_ref(); - self.0 = true; - Poll::Pending - } - } -} - -fn async_block(x: u8) -> impl Future { - async move { - await!(wake_and_yield_once()); - x - } -} - -fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future + 'a { - async move { - await!(wake_and_yield_once()); - *x - } -} - -fn async_nonmove_block(x: u8) -> impl Future { - async move { - let future = async { - await!(wake_and_yield_once()); - x - }; - await!(future) - } -} - -fn async_closure(x: u8) -> impl Future { - (async move |x: u8| -> u8 { - await!(wake_and_yield_once()); - x - })(x) -} - -fn async_closure_in_unsafe_block(x: u8) -> impl Future { - (unsafe { - async move |x: u8| unsafe_fn(await!(unsafe_async_fn(x))) - })(x) -} - -async fn async_fn(x: u8) -> u8 { - await!(wake_and_yield_once()); - x -} - -async fn generic_async_fn(x: T) -> T { - await!(wake_and_yield_once()); - x -} - -async fn async_fn_with_borrow(x: &u8) -> u8 { - await!(wake_and_yield_once()); - *x -} - -async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 { - await!(wake_and_yield_once()); - *x -} - -fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future + 'a { - async move { - await!(wake_and_yield_once()); - *x - } -} - -/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works -async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 { - await!(wake_and_yield_once()); - *x -} -*/ - -async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 { - await!(wake_and_yield_once()); - *x -} - -fn async_fn_with_internal_borrow(y: u8) -> impl Future { - async move { - await!(async_fn_with_borrow_named_lifetime(&y)) - } -} - -async unsafe fn unsafe_async_fn(x: u8) -> u8 { - await!(wake_and_yield_once()); - x -} - -unsafe fn unsafe_fn(x: u8) -> u8 { - x -} - -fn async_block_in_unsafe_block(x: u8) -> impl Future { - unsafe { - async move { - unsafe_fn(await!(unsafe_async_fn(x))) - } - } -} - -struct Foo; - -trait Bar { - fn foo() {} -} - -impl Foo { - async fn async_assoc_item(x: u8) -> u8 { - unsafe { - await!(unsafe_async_fn(x)) - } - } - - async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 { - await!(unsafe_async_fn(x)) - } -} - -fn test_future_yields_once_then_returns(f: F) -where - F: FnOnce(u8) -> Fut, - Fut: Future, -{ - let mut fut = Box::pin(f(9)); - let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); - let waker = ArcWake::into_waker(counter.clone()); - let mut cx = Context::from_waker(&waker); - assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx)); - assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx)); -} - -fn main() { - macro_rules! test { - ($($fn_name:expr,)*) => { $( - test_future_yields_once_then_returns($fn_name); - )* } - } - - macro_rules! test_with_borrow { - ($($fn_name:expr,)*) => { $( - test_future_yields_once_then_returns(|x| { - async move { - await!($fn_name(&x)) - } - }); - )* } - } - - test! { - async_block, - async_nonmove_block, - async_closure, - async_closure_in_unsafe_block, - async_fn, - generic_async_fn, - async_fn_with_internal_borrow, - async_block_in_unsafe_block, - Foo::async_assoc_item, - |x| { - async move { - unsafe { await!(unsafe_async_fn(x)) } - } - }, - |x| { - async move { - unsafe { await!(Foo::async_unsafe_assoc_item(x)) } - } - }, - } - test_with_borrow! { - async_block_with_borrow_named_lifetime, - async_fn_with_borrow, - async_fn_with_borrow_named_lifetime, - async_fn_with_impl_future_named_lifetime, - |x| { - async move { - await!(async_fn_multiple_args_named_lifetime(x, x)) - } - }, - } -} diff --git a/src/test/ui/async-await/multiple-lifetimes/named.rs b/src/test/ui/async-await/multiple-lifetimes/named.rs index 7d13d48bc8bbd..cd479e256b4e5 100644 --- a/src/test/ui/async-await/multiple-lifetimes/named.rs +++ b/src/test/ui/async-await/multiple-lifetimes/named.rs @@ -3,7 +3,7 @@ // Test that we can use async fns with multiple arbitrary lifetimes. -#![feature(arbitrary_self_types, async_await, await_macro)] +#![feature(async_await)] async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {} diff --git a/src/test/ui/feature-gate/await-macro.rs b/src/test/ui/feature-gate/await-macro.rs deleted file mode 100644 index 291db9ba41370..0000000000000 --- a/src/test/ui/feature-gate/await-macro.rs +++ /dev/null @@ -1,12 +0,0 @@ -// gate-test-await_macro -// edition:2018 - -#![feature(async_await)] - -async fn bar() {} - -async fn foo() { - await!(bar()); //~ ERROR `await!()` macro syntax is unstable, and will soon be removed -} - -fn main() {} diff --git a/src/test/ui/feature-gate/await-macro.stderr b/src/test/ui/feature-gate/await-macro.stderr deleted file mode 100644 index 0d4f03e211b52..0000000000000 --- a/src/test/ui/feature-gate/await-macro.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: `await!()` macro syntax is unstable, and will soon be removed in favor of `.await` syntax. - --> $DIR/await-macro.rs:9:5 - | -LL | await!(bar()); - | ^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add `#![feature(await_macro)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`.