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:
commit
56e8f29dbe
69 changed files with 1796 additions and 538 deletions
30
src/test/ui/async-fn-multiple-lifetimes.rs
Normal file
30
src/test/ui/async-fn-multiple-lifetimes.rs
Normal 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() {}
|
||||
32
src/test/ui/async-fn-multiple-lifetimes.stderr
Normal file
32
src/test/ui/async-fn-multiple-lifetimes.stderr
Normal 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`.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
20
src/test/ui/feature-gate-async-await-2015-edition.rs
Normal file
20
src/test/ui/feature-gate-async-await-2015-edition.rs
Normal 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
|
||||
}
|
||||
24
src/test/ui/feature-gate-async-await-2015-edition.stderr
Normal file
24
src/test/ui/feature-gate-async-await-2015-edition.stderr
Normal 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`.
|
||||
19
src/test/ui/feature-gate-async-await.rs
Normal file
19
src/test/ui/feature-gate-async-await.rs
Normal 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
|
||||
}
|
||||
27
src/test/ui/feature-gate-async-await.stderr
Normal file
27
src/test/ui/feature-gate-async-await.stderr
Normal 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`.
|
||||
18
src/test/ui/no-args-non-move-async-closure.rs
Normal file
18
src/test/ui/no-args-non-move-async-closure.rs
Normal 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
|
||||
}
|
||||
11
src/test/ui/no-args-non-move-async-closure.stderr
Normal file
11
src/test/ui/no-args-non-move-async-closure.stderr
Normal 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`.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue