mirror of https://github.com/rust-lang/rust.git
Support async trait bounds in macros
This commit is contained in:
parent
29f87ade9d
commit
9c8b107955
|
@ -27,6 +27,8 @@ parse_async_bound_modifier_in_2015 = `async` trait bounds are only allowed in Ru
|
|||
parse_async_fn_in_2015 = `async fn` is not permitted in Rust 2015
|
||||
.label = to use `async fn`, switch to Rust 2018 or later
|
||||
|
||||
parse_async_impl = `async` trait implementations are unsupported
|
||||
|
||||
parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 2018 or later
|
||||
|
||||
parse_async_move_order_incorrect = the order of `move` and `async` is incorrect
|
||||
|
|
|
@ -2975,3 +2975,10 @@ pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span);
|
|||
#[derive(Diagnostic)]
|
||||
#[diag(parse_invalid_offset_of)]
|
||||
pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_async_impl)]
|
||||
pub(crate) struct AsyncImpl {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
|
|
@ -562,6 +562,15 @@ impl<'a> Parser<'a> {
|
|||
self.sess.gated_spans.gate(sym::const_trait_impl, span);
|
||||
}
|
||||
|
||||
// Parse stray `impl async Trait`
|
||||
if (self.token.uninterpolated_span().at_least_rust_2018()
|
||||
&& self.token.is_keyword(kw::Async))
|
||||
|| self.is_kw_followed_by_ident(kw::Async)
|
||||
{
|
||||
self.bump();
|
||||
self.dcx().emit_err(errors::AsyncImpl { span: self.prev_token.span });
|
||||
}
|
||||
|
||||
let polarity = self.parse_polarity();
|
||||
|
||||
// Parse both types and traits as a type, then reinterpret if necessary.
|
||||
|
|
|
@ -778,9 +778,10 @@ impl<'a> Parser<'a> {
|
|||
|| self.check(&token::Not)
|
||||
|| self.check(&token::Question)
|
||||
|| self.check(&token::Tilde)
|
||||
|| self.check_keyword(kw::Const)
|
||||
|| self.check_keyword(kw::For)
|
||||
|| self.check(&token::OpenDelim(Delimiter::Parenthesis))
|
||||
|| self.check_keyword(kw::Const)
|
||||
|| self.check_keyword(kw::Async)
|
||||
}
|
||||
|
||||
/// Parses a bound according to the grammar:
|
||||
|
@ -882,11 +883,13 @@ impl<'a> Parser<'a> {
|
|||
BoundConstness::Never
|
||||
};
|
||||
|
||||
let asyncness = if self.token.span.at_least_rust_2018() && self.eat_keyword(kw::Async) {
|
||||
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018()
|
||||
&& self.eat_keyword(kw::Async)
|
||||
{
|
||||
self.sess.gated_spans.gate(sym::async_closure, self.prev_token.span);
|
||||
BoundAsyncness::Async(self.prev_token.span)
|
||||
} else if self.may_recover()
|
||||
&& self.token.span.is_rust_2015()
|
||||
&& self.token.uninterpolated_span().is_rust_2015()
|
||||
&& self.is_kw_followed_by_ident(kw::Async)
|
||||
{
|
||||
self.bump(); // eat `async`
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
struct F;
|
||||
|
||||
impl async Fn<()> for F {}
|
||||
//~^ ERROR expected type, found keyword `async`
|
||||
//~^ ERROR `async` trait implementations are unsupported
|
||||
//~| ERROR the precise format of `Fn`-family traits' type parameters is subject to change
|
||||
//~| ERROR manual implementations of `Fn` are experimental
|
||||
//~| ERROR expected a `FnMut()` closure, found `F`
|
||||
//~| ERROR not all trait items implemented, missing: `call`
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,8 +1,47 @@
|
|||
error: expected type, found keyword `async`
|
||||
error: `async` trait implementations are unsupported
|
||||
--> $DIR/impl-header.rs:5:6
|
||||
|
|
||||
LL | impl async Fn<()> for F {}
|
||||
| ^^^^^ expected type
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
|
||||
--> $DIR/impl-header.rs:5:12
|
||||
|
|
||||
LL | impl async Fn<()> for F {}
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
|
||||
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0183]: manual implementations of `Fn` are experimental
|
||||
--> $DIR/impl-header.rs:5:12
|
||||
|
|
||||
LL | impl async Fn<()> for F {}
|
||||
| ^^^^^^ manual implementations of `Fn` are experimental
|
||||
|
|
||||
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
||||
|
||||
error[E0277]: expected a `FnMut()` closure, found `F`
|
||||
--> $DIR/impl-header.rs:5:23
|
||||
|
|
||||
LL | impl async Fn<()> for F {}
|
||||
| ^ expected an `FnMut()` closure, found `F`
|
||||
|
|
||||
= help: the trait `FnMut<()>` is not implemented for `F`
|
||||
= note: wrap the `F` in a closure with no arguments: `|| { /* code */ }`
|
||||
note: required by a bound in `Fn`
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `call`
|
||||
--> $DIR/impl-header.rs:5:1
|
||||
|
|
||||
LL | impl async Fn<()> for F {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ missing `call` in implementation
|
||||
|
|
||||
= help: implement the missing item: `fn call(&self, _: ()) -> <Self as FnOnce<()>>::Output { todo!() }`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0046, E0183, E0277, E0658.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Demonstrates and records a theoretical regressions / breaking changes caused by the
|
||||
// introduction of async trait bounds.
|
||||
|
||||
// Setting the edition to 2018 since we don't regress `demo! { dyn async }` in Rust <2018.
|
||||
//@ edition:2018
|
||||
|
||||
macro_rules! demo {
|
||||
($ty:ty) => { compile_error!("ty"); };
|
||||
//~^ ERROR ty
|
||||
//~| ERROR ty
|
||||
(impl $c:ident Trait) => {};
|
||||
(dyn $c:ident Trait) => {};
|
||||
}
|
||||
|
||||
demo! { impl async Trait }
|
||||
//~^ ERROR async closures are unstable
|
||||
|
||||
demo! { dyn async Trait }
|
||||
//~^ ERROR async closures are unstable
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,47 @@
|
|||
error: ty
|
||||
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:8:19
|
||||
|
|
||||
LL | ($ty:ty) => { compile_error!("ty"); };
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | demo! { impl async Trait }
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: ty
|
||||
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:8:19
|
||||
|
|
||||
LL | ($ty:ty) => { compile_error!("ty"); };
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | demo! { dyn async Trait }
|
||||
| ------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: async closures are unstable
|
||||
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:15:14
|
||||
|
|
||||
LL | demo! { impl async Trait }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: to use an async block, remove the `||`: `async {`
|
||||
|
||||
error[E0658]: async closures are unstable
|
||||
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:18:13
|
||||
|
|
||||
LL | demo! { dyn async Trait }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: to use an async block, remove the `||`: `async {`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,12 @@
|
|||
//@ edition: 2021
|
||||
|
||||
macro_rules! x {
|
||||
($x:item) => {}
|
||||
}
|
||||
|
||||
x! {
|
||||
async fn foo() -> impl async Fn() { }
|
||||
//~^ ERROR async closures are unstable
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,14 @@
|
|||
error[E0658]: async closures are unstable
|
||||
--> $DIR/trait-bounds-in-macro.rs:8:28
|
||||
|
|
||||
LL | async fn foo() -> impl async Fn() { }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: to use an async block, remove the `||`: `async {`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -1,4 +1,4 @@
|
|||
//@ check-pass
|
||||
// This is just `mbe-async-trait-bound-theoretical-regression.rs` in practice.
|
||||
|
||||
//@ edition:2021
|
||||
// for the `impl` + keyword test
|
||||
|
@ -11,5 +11,7 @@ macro_rules! impl_primitive {
|
|||
}
|
||||
|
||||
impl_primitive!(impl async);
|
||||
//~^ ERROR expected identifier, found `<eof>`
|
||||
//~| ERROR async closures are unstable
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
error: expected identifier, found `<eof>`
|
||||
--> $DIR/bad-recover-kw-after-impl.rs:13:22
|
||||
|
|
||||
LL | ($ty:ty) => {
|
||||
| ------ while parsing argument for this `ty` macro fragment
|
||||
...
|
||||
LL | impl_primitive!(impl async);
|
||||
| ^^^^^ expected identifier
|
||||
|
||||
error[E0658]: async closures are unstable
|
||||
--> $DIR/bad-recover-kw-after-impl.rs:13:22
|
||||
|
|
||||
LL | impl_primitive!(impl async);
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: to use an async block, remove the `||`: `async {`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -8,7 +8,7 @@ fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect parentheses around t
|
|||
fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {} //~ ERROR incorrect parentheses around trait bounds
|
||||
|
||||
fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
|
||||
//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{`
|
||||
//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `async`, `const`, `for`, `~`, lifetime, or path, found `{`
|
||||
//~| ERROR at least one trait is required for an object type
|
||||
|
||||
fn foo4(_: &dyn <Drop + AsRef<str>>) {} //~ ERROR expected identifier, found `<`
|
||||
|
|
|
@ -34,11 +34,11 @@ error: expected parameter name, found `{`
|
|||
LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
|
||||
| ^ expected parameter name
|
||||
|
||||
error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{`
|
||||
error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `async`, `const`, `for`, `~`, lifetime, or path, found `{`
|
||||
--> $DIR/trait-object-delimiters.rs:10:17
|
||||
|
|
||||
LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
|
||||
| -^ expected one of 11 possible tokens
|
||||
| -^ expected one of 12 possible tokens
|
||||
| |
|
||||
| help: missing `,`
|
||||
|
||||
|
|
|
@ -6,15 +6,16 @@
|
|||
|
||||
macro_rules! demo {
|
||||
($ty:ty) => { compile_error!("ty"); };
|
||||
(impl $c:ident) => {};
|
||||
(dyn $c:ident) => {};
|
||||
//~^ ERROR ty
|
||||
//~| ERROR ty
|
||||
(impl $c:ident Trait) => {};
|
||||
(dyn $c:ident Trait) => {};
|
||||
}
|
||||
|
||||
demo! { impl const }
|
||||
//~^ ERROR expected identifier, found `<eof>`
|
||||
|
||||
demo! { dyn const }
|
||||
demo! { impl const Trait }
|
||||
//~^ ERROR const trait impls are experimental
|
||||
|
||||
demo! { dyn const Trait }
|
||||
//~^ ERROR const trait impls are experimental
|
||||
//~| ERROR expected identifier, found `<eof>`
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,31 +1,45 @@
|
|||
error: expected identifier, found `<eof>`
|
||||
--> $DIR/mbe-const-trait-bound-theoretical-regression.rs:13:14
|
||||
error: ty
|
||||
--> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19
|
||||
|
|
||||
LL | ($ty:ty) => { compile_error!("ty"); };
|
||||
| ------ while parsing argument for this `ty` macro fragment
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | demo! { impl const }
|
||||
| ^^^^^ expected identifier
|
||||
LL | demo! { impl const Trait }
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected identifier, found `<eof>`
|
||||
--> $DIR/mbe-const-trait-bound-theoretical-regression.rs:16:13
|
||||
error: ty
|
||||
--> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19
|
||||
|
|
||||
LL | ($ty:ty) => { compile_error!("ty"); };
|
||||
| ------ while parsing argument for this `ty` macro fragment
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | demo! { dyn const }
|
||||
| ^^^^^ expected identifier
|
||||
LL | demo! { dyn const Trait }
|
||||
| ------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: const trait impls are experimental
|
||||
--> $DIR/mbe-const-trait-bound-theoretical-regression.rs:16:13
|
||||
--> $DIR/mbe-const-trait-bound-theoretical-regression.rs:15:14
|
||||
|
|
||||
LL | demo! { dyn const }
|
||||
LL | demo! { impl const Trait }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: const trait impls are experimental
|
||||
--> $DIR/mbe-const-trait-bound-theoretical-regression.rs:18:13
|
||||
|
|
||||
LL | demo! { dyn const Trait }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
Loading…
Reference in New Issue