Skip to content

Commit

Permalink
Gate AsyncFn* under async_closure feature
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jul 23, 2024
1 parent 8bfcae7 commit b82f878
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 12 deletions.
22 changes: 15 additions & 7 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/ops/async_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand All @@ -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"]
Expand All @@ -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"]
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/async-await/async-fn/edition-2015.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
22 changes: 21 additions & 1 deletion tests/ui/async-await/async-fn/edition-2015.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
2 changes: 1 addition & 1 deletion tests/ui/async-await/async-fn/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@ edition: 2021
//@ build-pass

#![feature(async_fn_traits)]
#![feature(async_closure)]

extern crate block_on;

Expand Down

0 comments on commit b82f878

Please sign in to comment.