diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index d646150a620cd..2f85fc41f9a87 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -515,6 +515,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { "async closures are unstable", "to use an async block, remove the `||`: `async {`" ); + gate_all!( + async_trait_bounds, + "`async` trait bounds are unstable", + "use the desugared name of the async trait, such as `AsyncFn`" + ); gate_all!(async_for_loop, "`for await` loops are experimental"); gate_all!( closure_lifetime_binder, diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 5f83c211b386b..5dbbb089222c3 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -387,6 +387,8 @@ declare_features! ( (unstable, async_fn_track_caller, "1.73.0", Some(110011)), /// Allows `for await` loops. (unstable, async_for_loop, "1.77.0", Some(118898)), + /// Allows `async` trait bound modifier. + (unstable, async_trait_bounds, "CURRENT_RUSTC_VERSION", Some(62290)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows the use of `#[cfg()]`. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index c561ea3823d09..f0a47fc03e14d 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -943,7 +943,7 @@ impl<'a> Parser<'a> { let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() && self.eat_keyword(kw::Async) { - self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span); + self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span); BoundAsyncness::Async(self.prev_token.span) } else if self.may_recover() && self.token.uninterpolated_span().is_rust_2015() @@ -954,7 +954,7 @@ impl<'a> Parser<'a> { span: self.prev_token.span, help: HelpUseLatestEdition::new(), }); - self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span); + self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span); BoundAsyncness::Async(self.prev_token.span) } else { BoundAsyncness::Normal diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 21a74bd4020ac..2c0ddad1bee17 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -464,6 +464,7 @@ symbols! { async_for_loop, async_iterator, async_iterator_poll_next, + async_trait_bounds, atomic, atomic_mod, atomics, diff --git a/src/tools/miri/tests/pass/async-closure-captures.rs b/src/tools/miri/tests/pass/async-closure-captures.rs index cac26bfe14621..423ef7a5cf7e4 100644 --- a/src/tools/miri/tests/pass/async-closure-captures.rs +++ b/src/tools/miri/tests/pass/async-closure-captures.rs @@ -1,6 +1,6 @@ // Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync -#![feature(async_closure, noop_waker)] +#![feature(async_closure, noop_waker, async_trait_bounds)] use std::future::Future; use std::pin::pin; diff --git a/src/tools/miri/tests/pass/async-closure-drop.rs b/src/tools/miri/tests/pass/async-closure-drop.rs index 9b2fc2948bf45..264da5a951838 100644 --- a/src/tools/miri/tests/pass/async-closure-drop.rs +++ b/src/tools/miri/tests/pass/async-closure-drop.rs @@ -1,4 +1,4 @@ -#![feature(async_closure, noop_waker, async_fn_traits)] +#![feature(async_closure, noop_waker, async_trait_bounds)] use std::future::Future; use std::pin::pin; diff --git a/tests/ui/async-await/async-fn/dyn-pos.rs b/tests/ui/async-await/async-fn/dyn-pos.rs index 772c7d15cfd49..470e58d79ad9d 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.rs +++ b/tests/ui/async-await/async-fn/dyn-pos.rs @@ -2,7 +2,7 @@ #![feature(async_closure)] -fn foo(x: &dyn async Fn()) {} +fn foo(x: &dyn AsyncFn()) {} //~^ ERROR the trait `AsyncFn` cannot be made into an object //~| ERROR the trait `AsyncFnMut` cannot be made into an object //~| ERROR the trait `AsyncFnMut` cannot be made into an object diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr index 78e915d49e78b..222332da33c0a 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.stderr +++ b/tests/ui/async-await/async-fn/dyn-pos.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `AsyncFnMut` cannot be made into an object --> $DIR/dyn-pos.rs:5:16 | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object +LL | fn foo(x: &dyn AsyncFn()) {} + | ^^^^^^^^^ `AsyncFnMut` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL @@ -16,8 +16,8 @@ note: for a trait to be "dyn-compatible" it needs to allow building a vtable to error[E0038]: the trait `AsyncFnMut` cannot be made into an object --> $DIR/dyn-pos.rs:5:16 | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object +LL | fn foo(x: &dyn AsyncFn()) {} + | ^^^^^^^^^ `AsyncFnMut` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL @@ -32,8 +32,8 @@ note: for a trait to be "dyn-compatible" it needs to allow building a vtable to error[E0038]: the trait `AsyncFnMut` cannot be made into an object --> $DIR/dyn-pos.rs:5:16 | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object +LL | fn foo(x: &dyn AsyncFn()) {} + | ^^^^^^^^^ `AsyncFnMut` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL @@ -48,8 +48,8 @@ note: for a trait to be "dyn-compatible" it needs to allow building a vtable to error[E0038]: the trait `AsyncFn` cannot be made into an object --> $DIR/dyn-pos.rs:5:12 | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^^^^^ `AsyncFn` cannot be made into an object +LL | fn foo(x: &dyn AsyncFn()) {} + | ^^^^^^^^^^^^^ `AsyncFn` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL diff --git a/tests/ui/async-await/async-fn/edition-2015.rs b/tests/ui/async-await/async-fn/edition-2015.rs index e38179758f6bb..7fc62a8dd93db 100644 --- a/tests/ui/async-await/async-fn/edition-2015.rs +++ b/tests/ui/async-await/async-fn/edition-2015.rs @@ -1,8 +1,8 @@ fn foo(x: impl async Fn()) -> impl async Fn() { x } //~^ ERROR `async` trait bounds are only allowed in Rust 2018 or later //~| ERROR `async` trait bounds are only allowed in Rust 2018 or later -//~| ERROR async closures are unstable -//~| ERROR async closures are unstable +//~| ERROR `async` trait bounds are unstable +//~| ERROR `async` trait bounds are unstable //~| ERROR use of unstable library feature `async_closure` //~| ERROR use of unstable library feature `async_closure` diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr index 25101cb65df51..8f41db17546af 100644 --- a/tests/ui/async-await/async-fn/edition-2015.stderr +++ b/tests/ui/async-await/async-fn/edition-2015.stderr @@ -16,27 +16,27 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/edition-2015.rs:1:16 | LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } | ^^^^^ | = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` 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 {` + = help: use the desugared name of the async trait, such as `AsyncFn` -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/edition-2015.rs:1:36 | LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } | ^^^^^ | = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` 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 {` + = help: use the desugared name of the async trait, such as `AsyncFn` error[E0658]: use of unstable library feature `async_closure` --> $DIR/edition-2015.rs:1:42 diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs index abc429772fdc8..ea67831b68e67 100644 --- a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs +++ b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs @@ -13,9 +13,9 @@ macro_rules! demo { } demo! { impl async Trait } -//~^ ERROR async closures are unstable +//~^ ERROR `async` trait bounds are unstable demo! { dyn async Trait } -//~^ ERROR async closures are unstable +//~^ ERROR `async` trait bounds are unstable fn main() {} diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr index 13b8e72b49dc6..a463944d1133e 100644 --- a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr +++ b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr @@ -20,27 +20,27 @@ LL | demo! { dyn async Trait } | = 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 +error[E0658]: `async` trait bounds are unstable --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:15:14 | LL | demo! { impl async Trait } | ^^^^^ | = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` 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 {` + = help: use the desugared name of the async trait, such as `AsyncFn` -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:18:13 | LL | demo! { dyn async Trait } | ^^^^^ | = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` 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 {` + = help: use the desugared name of the async trait, such as `AsyncFn` error: aborting due to 4 previous errors diff --git a/tests/ui/async-await/async-fn/not-a-trait.rs b/tests/ui/async-await/async-fn/not-a-trait.rs index 0d22cbd2c0730..5cf23f2456a82 100644 --- a/tests/ui/async-await/async-fn/not-a-trait.rs +++ b/tests/ui/async-await/async-fn/not-a-trait.rs @@ -1,6 +1,6 @@ //@ edition:2018 -#![feature(async_closure)] +#![feature(async_trait_bounds)] struct S; diff --git a/tests/ui/async-await/async-fn/sugar.rs b/tests/ui/async-await/async-fn/sugar.rs index 29b6abc814a42..0225b666ac582 100644 --- a/tests/ui/async-await/async-fn/sugar.rs +++ b/tests/ui/async-await/async-fn/sugar.rs @@ -1,7 +1,7 @@ //@ edition: 2021 //@ check-pass -#![feature(async_closure)] +#![feature(async_closure, async_trait_bounds)] async fn foo() {} diff --git a/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs b/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs index 329a1528e8b4f..654883966f403 100644 --- a/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs +++ b/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs @@ -6,7 +6,7 @@ macro_rules! x { x! { async fn foo() -> impl async Fn() { } - //~^ ERROR async closures are unstable + //~^ ERROR `async` trait bounds are unstable } fn main() {} diff --git a/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr b/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr index f68c09737dbc7..259e13cd1fe2c 100644 --- a/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr +++ b/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr @@ -1,13 +1,13 @@ -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/trait-bounds-in-macro.rs:8:28 | LL | async fn foo() -> impl async Fn() { } | ^^^^^ | = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` 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 {` + = help: use the desugared name of the async trait, such as `AsyncFn` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-fn/wrong-trait.rs b/tests/ui/async-await/async-fn/wrong-trait.rs index e6fb0b46712de..38d6bb1d01a99 100644 --- a/tests/ui/async-await/async-fn/wrong-trait.rs +++ b/tests/ui/async-await/async-fn/wrong-trait.rs @@ -1,6 +1,6 @@ //@ edition:2018 -#![feature(async_closure)] +#![feature(async_trait_bounds)] trait Foo {} diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs new file mode 100644 index 0000000000000..db5d7aa06d221 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs @@ -0,0 +1,7 @@ +//@ edition: 2021 + +fn test(_: impl async Fn()) {} +//~^ ERROR `async` trait bounds are unstable +//~| ERROR use of unstable library feature `async_closure` + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr new file mode 100644 index 0000000000000..abc7e37c45f2c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr @@ -0,0 +1,24 @@ +error[E0658]: `async` trait bounds are unstable + --> $DIR/feature-gate-async-trait-bounds.rs:3:17 + | +LL | fn test(_: impl async Fn()) {} + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_trait_bounds)]` 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: use the desugared name of the async trait, such as `AsyncFn` + +error[E0658]: use of unstable library feature `async_closure` + --> $DIR/feature-gate-async-trait-bounds.rs:3:23 + | +LL | fn test(_: impl async Fn()) {} + | ^^^^ + | + = note: see issue #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 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs index 46121308fa07c..cac5ae177d2fb 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -7,7 +7,7 @@ fn polarity() -> impl Sized + ?use<> {} fn asyncness() -> impl Sized + async use<> {} //~^ ERROR expected identifier, found keyword `use` //~| ERROR cannot find trait `r#use` in this scope -//~| ERROR async closures are unstable +//~| ERROR `async` trait bounds are unstable fn constness() -> impl Sized + const use<> {} //~^ ERROR expected identifier, found keyword `use` diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index 16e7470debf09..d4b5b47b41b5e 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -46,16 +46,16 @@ error[E0405]: cannot find trait `r#use` in this scope LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ not found in this scope -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/bound-modifiers.rs:7:32 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^^^ | = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` 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 {` + = help: use the desugared name of the async trait, such as `AsyncFn` error[E0658]: const trait impls are experimental --> $DIR/bound-modifiers.rs:12:32 diff --git a/tests/ui/parser/bad-recover-kw-after-impl.rs b/tests/ui/parser/bad-recover-kw-after-impl.rs index 15c0b377c8ae5..964d32c55bc19 100644 --- a/tests/ui/parser/bad-recover-kw-after-impl.rs +++ b/tests/ui/parser/bad-recover-kw-after-impl.rs @@ -12,6 +12,6 @@ macro_rules! impl_primitive { impl_primitive!(impl async); //~^ ERROR expected identifier, found `` -//~| ERROR async closures are unstable +//~| ERROR `async` trait bounds are unstable fn main() {} diff --git a/tests/ui/parser/bad-recover-kw-after-impl.stderr b/tests/ui/parser/bad-recover-kw-after-impl.stderr index f617cf6549886..7a8979db165a5 100644 --- a/tests/ui/parser/bad-recover-kw-after-impl.stderr +++ b/tests/ui/parser/bad-recover-kw-after-impl.stderr @@ -7,16 +7,16 @@ LL | ($ty:ty) => { LL | impl_primitive!(impl async); | ^^^^^ expected identifier -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/bad-recover-kw-after-impl.rs:13:22 | LL | impl_primitive!(impl async); | ^^^^^ | = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` 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 {` + = help: use the desugared name of the async trait, such as `AsyncFn` error: aborting due to 2 previous errors