about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs22
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/core/src/ops/async_function.rs6
-rw-r--r--tests/ui/async-await/async-fn/edition-2015.rs2
-rw-r--r--tests/ui/async-await/async-fn/edition-2015.stderr22
-rw-r--r--tests/ui/async-await/async-fn/simple.rs2
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 6303584bb78..ac36b074609 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<DefId> {
         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 a7715740cbd..4491a717dc2 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 48d1042d9df..37fac2b126f 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<Args: Tuple>: AsyncFnMut<Args> {
 /// 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<Args: Tuple>: AsyncFnOnce<Args> {
 /// 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 83b9d415dda..50448313b30 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 0029d53868d..23ffee0d0a6 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 <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
+
+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 <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
+
+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 21972ba5aef..3f15b08560a 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;