From b82f878f03a9133f61f4b652fea906322747a379 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 23 Jul 2024 19:10:22 -0400 Subject: [PATCH] Gate AsyncFn* under async_closure feature --- compiler/rustc_ast_lowering/src/path.rs | 22 +++++++++++++------ library/alloc/src/lib.rs | 1 + library/core/src/ops/async_function.rs | 6 ++--- tests/ui/async-await/async-fn/edition-2015.rs | 2 ++ .../async-await/async-fn/edition-2015.stderr | 22 ++++++++++++++++++- tests/ui/async-await/async-fn/simple.rs | 2 +- 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 6303584bb7846..ac36b07460969 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -44,13 +44,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut res = self.lower_res(base_res); // When we have an `async` kw on a bound, map the trait it resolves to. - let mut bound_modifier_allowed_features = None; if let Some(TraitBoundModifiers { asyncness: BoundAsyncness::Async(_), .. }) = modifiers { match res { Res::Def(DefKind::Trait, def_id) => { - if let Some((async_def_id, features)) = self.map_trait_to_async_trait(def_id) { + if let Some(async_def_id) = self.map_trait_to_async_trait(def_id) { res = Res::Def(DefKind::Trait, async_def_id); - bound_modifier_allowed_features = Some(features); } else { self.dcx().emit_err(AsyncBoundOnlyForFnTraits { span: p.span }); } @@ -67,6 +65,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + // Ungate the `async_fn_traits` feature in the path if the trait is + // named via either `async Fn*()` or `AsyncFn*()`. + let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res + && self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some() + { + Some(self.allow_async_fn_traits.clone()) + } else { + None + }; + let path_span_lo = p.span.shrink_to_lo(); let proj_start = p.segments.len() - unresolved_segments; let path = self.arena.alloc(hir::Path { @@ -506,14 +514,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// This only needs to be done until we unify `AsyncFn` and `Fn` traits into one /// that is generic over `async`ness, if that's ever possible, or modify the /// lowering of `async Fn()` bounds to desugar to another trait like `LendingFn`. - fn map_trait_to_async_trait(&self, def_id: DefId) -> Option<(DefId, Lrc<[Symbol]>)> { + fn map_trait_to_async_trait(&self, def_id: DefId) -> Option { let lang_items = self.tcx.lang_items(); if Some(def_id) == lang_items.fn_trait() { - Some((lang_items.async_fn_trait()?, self.allow_async_fn_traits.clone())) + lang_items.async_fn_trait() } else if Some(def_id) == lang_items.fn_mut_trait() { - Some((lang_items.async_fn_mut_trait()?, self.allow_async_fn_traits.clone())) + lang_items.async_fn_mut_trait() } else if Some(def_id) == lang_items.fn_once_trait() { - Some((lang_items.async_fn_once_trait()?, self.allow_async_fn_traits.clone())) + lang_items.async_fn_once_trait() } else { None } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index a7715740cbd8f..4491a717dc2ea 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -101,6 +101,7 @@ #![feature(array_windows)] #![feature(ascii_char)] #![feature(assert_matches)] +#![feature(async_closure)] #![feature(async_fn_traits)] #![feature(async_iterator)] #![feature(clone_to_uninit)] diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs index 48d1042d9df4a..37fac2b126fac 100644 --- a/library/core/src/ops/async_function.rs +++ b/library/core/src/ops/async_function.rs @@ -4,7 +4,7 @@ use crate::marker::Tuple; /// An async-aware version of the [`Fn`](crate::ops::Fn) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_fn_traits", issue = "none")] +#[unstable(feature = "async_closure", issue = "62290")] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -18,7 +18,7 @@ pub trait AsyncFn: AsyncFnMut { /// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_fn_traits", issue = "none")] +#[unstable(feature = "async_closure", issue = "62290")] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -39,7 +39,7 @@ pub trait AsyncFnMut: AsyncFnOnce { /// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_fn_traits", issue = "none")] +#[unstable(feature = "async_closure", issue = "62290")] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] diff --git a/tests/ui/async-await/async-fn/edition-2015.rs b/tests/ui/async-await/async-fn/edition-2015.rs index 83b9d415ddab4..50448313b301a 100644 --- a/tests/ui/async-await/async-fn/edition-2015.rs +++ b/tests/ui/async-await/async-fn/edition-2015.rs @@ -3,5 +3,7 @@ fn foo(x: impl async Fn()) -> impl async Fn() { x } //~| ERROR `async` trait bounds are only allowed in Rust 2018 or later //~| ERROR async closures are unstable //~| ERROR async closures are unstable +//~| ERROR use of unstable library feature 'async_closure' +//~| ERROR use of unstable library feature 'async_closure' fn main() {} diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr index 0029d53868d4f..23ffee0d0a6b2 100644 --- a/tests/ui/async-await/async-fn/edition-2015.stderr +++ b/tests/ui/async-await/async-fn/edition-2015.stderr @@ -38,6 +38,26 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } = 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 +error[E0658]: use of unstable library feature 'async_closure' + --> $DIR/edition-2015.rs:1:22 + | +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 + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature 'async_closure' + --> $DIR/edition-2015.rs:1:42 + | +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 + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/async-fn/simple.rs b/tests/ui/async-await/async-fn/simple.rs index 21972ba5aefad..3f15b08560af2 100644 --- a/tests/ui/async-await/async-fn/simple.rs +++ b/tests/ui/async-await/async-fn/simple.rs @@ -2,7 +2,7 @@ //@ edition: 2021 //@ build-pass -#![feature(async_fn_traits)] +#![feature(async_closure)] extern crate block_on;