diff options
| author | bors <bors@rust-lang.org> | 2024-02-10 07:15:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-02-10 07:15:15 +0000 |
| commit | 757b8efed44eacbbc6baf4a393f77d23d5be90c8 (patch) | |
| tree | 3d1898c476ccb02da378740f1440ebf590084fcb /library/alloc | |
| parent | 68125c72d389060fe9aaee8d87ebd834f417c9fc (diff) | |
| parent | 540be28f6c2571e7be3ab3936b62635fa0d3caf3 (diff) | |
| download | rust-757b8efed44eacbbc6baf4a393f77d23d5be90c8.tar.gz rust-757b8efed44eacbbc6baf4a393f77d23d5be90c8.zip | |
Auto merge of #120712 - compiler-errors:async-closures-harmonize, r=oli-obk
Harmonize `AsyncFn` implementations, make async closures conditionally impl `Fn*` traits This PR implements several changes to the built-in and libcore-provided implementations of `Fn*` and `AsyncFn*` to address two problems: 1. async closures do not implement the `Fn*` family traits, leading to breakage: https://crater-reports.s3.amazonaws.com/pr-120361/index.html 2. *references* to async closures do not implement `AsyncFn*`, as a consequence of the existing blanket impls of the shape `AsyncFn for F where F: Fn, F::Output: Future`. In order to fix (1.), we implement `Fn` traits appropriately for async closures. It turns out that async closures can: * always implement `FnOnce`, meaning that they're drop-in compatible with `FnOnce`-bound combinators like `Option::map`. * conditionally implement `Fn`/`FnMut` if they have no captures, which means that existing usages of async closures should *probably* work without breakage (crater checking this: https://github.com/rust-lang/rust/pull/120712#issuecomment-1930587805). In order to fix (2.), we make all of the built-in callables implement `AsyncFn*` via built-in impls, and instead adjust the blanket impls for `AsyncFn*` provided by libcore to match the blanket impls for `Fn*`.
Diffstat (limited to 'library/alloc')
| -rw-r--r-- | library/alloc/src/boxed.rs | 29 | ||||
| -rw-r--r-- | library/alloc/src/lib.rs | 1 |
2 files changed, 30 insertions, 0 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 953041b8c20..92600b8e5bd 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -159,6 +159,7 @@ use core::iter::FusedIterator; use core::marker::Tuple; use core::marker::Unsize; use core::mem::{self, SizedTypeProperties}; +use core::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; use core::ops::{ CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver, }; @@ -2030,6 +2031,34 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> { } } +#[unstable(feature = "async_fn_traits", issue = "none")] +impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args> for Box<F, A> { + type Output = F::Output; + type CallOnceFuture = F::CallOnceFuture; + + extern "rust-call" fn async_call_once(self, args: Args) -> Self::CallOnceFuture { + F::async_call_once(*self, args) + } +} + +#[unstable(feature = "async_fn_traits", issue = "none")] +impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> for Box<F, A> { + type CallMutFuture<'a> = F::CallMutFuture<'a> where Self: 'a; + + extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallMutFuture<'_> { + F::async_call_mut(self, args) + } +} + +#[unstable(feature = "async_fn_traits", issue = "none")] +impl<Args: Tuple, F: AsyncFn<Args> + ?Sized, A: Allocator> AsyncFn<Args> for Box<F, A> { + type CallFuture<'a> = F::CallFuture<'a> where Self: 'a; + + extern "rust-call" fn async_call(&self, args: Args) -> Self::CallFuture<'_> { + F::async_call(self, args) + } +} + #[unstable(feature = "coerce_unsized", issue = "18598")] impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 96d43e11dc6..3341b564d1f 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -106,6 +106,7 @@ #![feature(array_windows)] #![feature(ascii_char)] #![feature(assert_matches)] +#![feature(async_fn_traits)] #![feature(async_iterator)] #![feature(coerce_unsized)] #![feature(const_align_of_val)] |
