Auto merge of #51580 - cramertj:async-await, r=eddyb

async/await

This PR implements `async`/`await` syntax for `async fn` in Rust 2015 and `async` closures and `async` blocks in Rust 2018 (tracking issue: https://github.com/rust-lang/rust/issues/50547). Limitations: non-`move` async closures with arguments are currently not supported, nor are `async fn` with multiple different input lifetimes. These limitations are not fundamental and will be removed in the future, however I'd like to go ahead and get this PR merged so we can start experimenting with this in combination with futures 0.3.

Based on https://github.com/rust-lang/rust/pull/51414.
cc @petrochenkov for parsing changes.
r? @eddyb
This commit is contained in:
bors 2018-06-23 09:02:45 +00:00
commit 56e8f29dbe
69 changed files with 1796 additions and 538 deletions

View file

@ -0,0 +1,30 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --edition=2018
#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
use std::ops::Add;
async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
//~^ ERROR multiple different lifetimes used in arguments of `async fn`
async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
_: impl for<'a> Add<&'a u8>,
_: impl for<'b> Add<&'b u8>,
_: &'c u8,
) {}
async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
//~^ ERROR multiple elided lifetimes used
//~^^ ERROR missing lifetime specifier
fn main() {}

View file

@ -0,0 +1,32 @@
error[E0725]: multiple different lifetimes used in arguments of `async fn`
--> $DIR/async-fn-multiple-lifetimes.rs:17:49
|
LL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
| --^^^^^^^^^-- different lifetime here
| |
| first lifetime here
|
= help: `async fn` can only accept borrowed values with identical lifetimes
error[E0726]: multiple elided lifetimes used in arguments of `async fn`
--> $DIR/async-fn-multiple-lifetimes.rs:26:39
|
LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
| -^^^^^^^- different lifetime here
| |
| first lifetime here
|
= help: consider giving these arguments named lifetimes
error[E0106]: missing lifetime specifier
--> $DIR/async-fn-multiple-lifetimes.rs:26:39
|
LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_` or `_`
error: aborting due to 3 previous errors
Some errors occurred: E0106, E0725, E0726.
For more information about an error, try `rustc --explain E0106`.

View file

@ -38,11 +38,11 @@ LL | L = M; //~ ERROR missing
LL | | Z = { 2 + 3 }; //~ ERROR expected one of
| |____^ missing `fn`, `type`, or `const`
error: expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
--> $DIR/issue-40006.rs:23:18
|
LL | Z = { 2 + 3 }; //~ ERROR expected one of
| ^ expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}` here
| ^ expected one of 7 possible tokens here
error: expected one of `!` or `::`, found `(`
--> $DIR/issue-40006.rs:24:9

View file

@ -25,7 +25,7 @@ pub fn check_async() {
r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
r#async = consumes_async_raw!(r#async); // OK
if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
if passes_ident!(async) == 1 {}
if passes_ident!(r#async) == 1 {} // OK
module::async(); //~ ERROR expected identifier, found reserved keyword `async`
module::r#async(); // OK

View file

@ -22,11 +22,11 @@ error: no rules expected the token `async`
LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
| ^^^^^
error: expected expression, found reserved keyword `async`
--> $DIR/edition-keywords-2018-2015-parsing.rs:28:22
error: expected one of `move`, `|`, or `||`, found `<eof>`
--> <passes_ident macros>:1:22
|
LL | if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
| ^^^^^ expected expression
LL | ( $ i : ident ) => ( $ i )
| ^^^ expected one of `move`, `|`, or `||` here
error: aborting due to 5 previous errors

View file

@ -25,7 +25,7 @@ pub fn check_async() {
r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
r#async = consumes_async_raw!(r#async); // OK
if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
if passes_ident!(async) == 1 {}
if passes_ident!(r#async) == 1 {} // OK
module::async(); //~ ERROR expected identifier, found reserved keyword `async`
module::r#async(); // OK

View file

@ -22,11 +22,11 @@ error: no rules expected the token `async`
LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
| ^^^^^
error: expected expression, found reserved keyword `async`
--> $DIR/edition-keywords-2018-2018-parsing.rs:28:22
error: expected one of `move`, `|`, or `||`, found `<eof>`
--> <passes_ident macros>:1:22
|
LL | if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
| ^^^^^ expected expression
LL | ( $ i : ident ) => ( $ i )
| ^^^ expected one of `move`, `|`, or `||` here
error: aborting due to 5 previous errors

View file

@ -0,0 +1,20 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --edition=2015
#![feature(futures_api)]
async fn foo() {} //~ ERROR async fn is unstable
fn main() {
let _ = async {}; //~ ERROR cannot find struct, variant or union type `async`
let _ = async || {}; //~ ERROR cannot find value `async` in this scope
}

View file

@ -0,0 +1,24 @@
error[E0422]: cannot find struct, variant or union type `async` in this scope
--> $DIR/feature-gate-async-await-2015-edition.rs:18:13
|
LL | let _ = async {}; //~ ERROR cannot find struct, variant or union type `async`
| ^^^^^ not found in this scope
error[E0425]: cannot find value `async` in this scope
--> $DIR/feature-gate-async-await-2015-edition.rs:19:13
|
LL | let _ = async || {}; //~ ERROR cannot find value `async` in this scope
| ^^^^^ not found in this scope
error[E0658]: async fn is unstable (see issue #50547)
--> $DIR/feature-gate-async-await-2015-edition.rs:15:1
|
LL | async fn foo() {} //~ ERROR async fn is unstable
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(async_await)] to the crate attributes to enable
error: aborting due to 3 previous errors
Some errors occurred: E0422, E0425, E0658.
For more information about an error, try `rustc --explain E0422`.

View file

@ -0,0 +1,19 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --edition=2018
#![feature(futures_api)]
async fn foo() {} //~ ERROR async fn is unstable
fn main() {
let _ = async {}; //~ ERROR async blocks are unstable
let _ = async || {}; //~ ERROR async closures are unstable
}

View file

@ -0,0 +1,27 @@
error[E0658]: async fn is unstable (see issue #50547)
--> $DIR/feature-gate-async-await.rs:14:1
|
LL | async fn foo() {} //~ ERROR async fn is unstable
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(async_await)] to the crate attributes to enable
error[E0658]: async blocks are unstable (see issue #50547)
--> $DIR/feature-gate-async-await.rs:17:13
|
LL | let _ = async {}; //~ ERROR async blocks are unstable
| ^^^^^^^^
|
= help: add #![feature(async_await)] to the crate attributes to enable
error[E0658]: async closures are unstable (see issue #50547)
--> $DIR/feature-gate-async-await.rs:18:13
|
LL | let _ = async || {}; //~ ERROR async closures are unstable
| ^^^^^^^^^^^
|
= help: add #![feature(async_await)] to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -0,0 +1,18 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --edition=2018
#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
fn main() {
let _ = async |x: u8| {};
//~^ ERROR `async` non-`move` closures with arguments are not currently supported
}

View file

@ -0,0 +1,11 @@
error[E0727]: `async` non-`move` closures with arguments are not currently supported
--> $DIR/no-args-non-move-async-closure.rs:16:13
|
LL | let _ = async |x: u8| {};
| ^^^^^^^^^^^^^
|
= help: consider using `let` statements to manually capture variables by reference before entering an `async move` closure
error: aborting due to previous error
For more information about this error, try `rustc --explain E0727`.

View file

@ -1,8 +1,8 @@
error: expected one of `(`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found `}`
error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found `}`
--> $DIR/issue-41155.rs:13:1
|
LL | pub
| - expected one of 7 possible tokens here
| - expected one of 8 possible tokens here
LL | } //~ ERROR expected one of
| ^ unexpected token