Skip to content

Commit b82f878

Browse files
Gate AsyncFn* under async_closure feature
1 parent 8bfcae7 commit b82f878

File tree

6 files changed

+43
-12
lines changed

6 files changed

+43
-12
lines changed

compiler/rustc_ast_lowering/src/path.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
4444
let mut res = self.lower_res(base_res);
4545

4646
// When we have an `async` kw on a bound, map the trait it resolves to.
47-
let mut bound_modifier_allowed_features = None;
4847
if let Some(TraitBoundModifiers { asyncness: BoundAsyncness::Async(_), .. }) = modifiers {
4948
match res {
5049
Res::Def(DefKind::Trait, def_id) => {
51-
if let Some((async_def_id, features)) = self.map_trait_to_async_trait(def_id) {
50+
if let Some(async_def_id) = self.map_trait_to_async_trait(def_id) {
5251
res = Res::Def(DefKind::Trait, async_def_id);
53-
bound_modifier_allowed_features = Some(features);
5452
} else {
5553
self.dcx().emit_err(AsyncBoundOnlyForFnTraits { span: p.span });
5654
}
@@ -67,6 +65,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6765
}
6866
}
6967

68+
// Ungate the `async_fn_traits` feature in the path if the trait is
69+
// named via either `async Fn*()` or `AsyncFn*()`.
70+
let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res
71+
&& self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some()
72+
{
73+
Some(self.allow_async_fn_traits.clone())
74+
} else {
75+
None
76+
};
77+
7078
let path_span_lo = p.span.shrink_to_lo();
7179
let proj_start = p.segments.len() - unresolved_segments;
7280
let path = self.arena.alloc(hir::Path {
@@ -506,14 +514,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
506514
/// This only needs to be done until we unify `AsyncFn` and `Fn` traits into one
507515
/// that is generic over `async`ness, if that's ever possible, or modify the
508516
/// lowering of `async Fn()` bounds to desugar to another trait like `LendingFn`.
509-
fn map_trait_to_async_trait(&self, def_id: DefId) -> Option<(DefId, Lrc<[Symbol]>)> {
517+
fn map_trait_to_async_trait(&self, def_id: DefId) -> Option<DefId> {
510518
let lang_items = self.tcx.lang_items();
511519
if Some(def_id) == lang_items.fn_trait() {
512-
Some((lang_items.async_fn_trait()?, self.allow_async_fn_traits.clone()))
520+
lang_items.async_fn_trait()
513521
} else if Some(def_id) == lang_items.fn_mut_trait() {
514-
Some((lang_items.async_fn_mut_trait()?, self.allow_async_fn_traits.clone()))
522+
lang_items.async_fn_mut_trait()
515523
} else if Some(def_id) == lang_items.fn_once_trait() {
516-
Some((lang_items.async_fn_once_trait()?, self.allow_async_fn_traits.clone()))
524+
lang_items.async_fn_once_trait()
517525
} else {
518526
None
519527
}

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
#![feature(array_windows)]
102102
#![feature(ascii_char)]
103103
#![feature(assert_matches)]
104+
#![feature(async_closure)]
104105
#![feature(async_fn_traits)]
105106
#![feature(async_iterator)]
106107
#![feature(clone_to_uninit)]

library/core/src/ops/async_function.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::marker::Tuple;
44
/// An async-aware version of the [`Fn`](crate::ops::Fn) trait.
55
///
66
/// All `async fn` and functions returning futures implement this trait.
7-
#[unstable(feature = "async_fn_traits", issue = "none")]
7+
#[unstable(feature = "async_closure", issue = "62290")]
88
#[rustc_paren_sugar]
99
#[fundamental]
1010
#[must_use = "async closures are lazy and do nothing unless called"]
@@ -18,7 +18,7 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
1818
/// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait.
1919
///
2020
/// All `async fn` and functions returning futures implement this trait.
21-
#[unstable(feature = "async_fn_traits", issue = "none")]
21+
#[unstable(feature = "async_closure", issue = "62290")]
2222
#[rustc_paren_sugar]
2323
#[fundamental]
2424
#[must_use = "async closures are lazy and do nothing unless called"]
@@ -39,7 +39,7 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
3939
/// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait.
4040
///
4141
/// All `async fn` and functions returning futures implement this trait.
42-
#[unstable(feature = "async_fn_traits", issue = "none")]
42+
#[unstable(feature = "async_closure", issue = "62290")]
4343
#[rustc_paren_sugar]
4444
#[fundamental]
4545
#[must_use = "async closures are lazy and do nothing unless called"]

tests/ui/async-await/async-fn/edition-2015.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ fn foo(x: impl async Fn()) -> impl async Fn() { x }
33
//~| ERROR `async` trait bounds are only allowed in Rust 2018 or later
44
//~| ERROR async closures are unstable
55
//~| ERROR async closures are unstable
6+
//~| ERROR use of unstable library feature 'async_closure'
7+
//~| ERROR use of unstable library feature 'async_closure'
68

79
fn main() {}

tests/ui/async-await/async-fn/edition-2015.stderr

+21-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
3838
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3939
= help: to use an async block, remove the `||`: `async {`
4040

41-
error: aborting due to 4 previous errors
41+
error[E0658]: use of unstable library feature 'async_closure'
42+
--> $DIR/edition-2015.rs:1:22
43+
|
44+
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
45+
| ^^^^
46+
|
47+
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
48+
= help: add `#![feature(async_closure)]` to the crate attributes to enable
49+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
50+
51+
error[E0658]: use of unstable library feature 'async_closure'
52+
--> $DIR/edition-2015.rs:1:42
53+
|
54+
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
55+
| ^^^^
56+
|
57+
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
58+
= help: add `#![feature(async_closure)]` to the crate attributes to enable
59+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
60+
61+
error: aborting due to 6 previous errors
4262

4363
For more information about this error, try `rustc --explain E0658`.

tests/ui/async-await/async-fn/simple.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//@ edition: 2021
33
//@ build-pass
44

5-
#![feature(async_fn_traits)]
5+
#![feature(async_closure)]
66

77
extern crate block_on;
88

0 commit comments

Comments
 (0)