| 1 | use crate::future::Future; |
| 2 | use crate::marker::Tuple; |
| 3 | |
| 4 | /// An async-aware version of the [`Fn`](crate::ops::Fn) trait. |
| 5 | /// |
| 6 | /// All `async fn` and functions returning futures implement this trait. |
| 7 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 8 | #[rustc_paren_sugar ] |
| 9 | #[must_use = "async closures are lazy and do nothing unless called" ] |
| 10 | #[lang = "async_fn" ] |
| 11 | pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> { |
| 12 | /// Call the [`AsyncFn`], returning a future which may borrow from the called closure. |
| 13 | #[unstable (feature = "async_fn_traits" , issue = "none" )] |
| 14 | extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_>; |
| 15 | } |
| 16 | |
| 17 | /// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait. |
| 18 | /// |
| 19 | /// All `async fn` and functions returning futures implement this trait. |
| 20 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 21 | #[rustc_paren_sugar ] |
| 22 | #[must_use = "async closures are lazy and do nothing unless called" ] |
| 23 | #[lang = "async_fn_mut" ] |
| 24 | pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> { |
| 25 | /// Future returned by [`AsyncFnMut::async_call_mut`] and [`AsyncFn::async_call`]. |
| 26 | #[unstable (feature = "async_fn_traits" , issue = "none" )] |
| 27 | #[lang = "call_ref_future" ] |
| 28 | type CallRefFuture<'a>: Future<Output = Self::Output> |
| 29 | where |
| 30 | Self: 'a; |
| 31 | |
| 32 | /// Call the [`AsyncFnMut`], returning a future which may borrow from the called closure. |
| 33 | #[unstable (feature = "async_fn_traits" , issue = "none" )] |
| 34 | extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallRefFuture<'_>; |
| 35 | } |
| 36 | |
| 37 | /// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait. |
| 38 | /// |
| 39 | /// All `async fn` and functions returning futures implement this trait. |
| 40 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 41 | #[rustc_paren_sugar ] |
| 42 | #[must_use = "async closures are lazy and do nothing unless called" ] |
| 43 | #[lang = "async_fn_once" ] |
| 44 | pub trait AsyncFnOnce<Args: Tuple> { |
| 45 | /// Future returned by [`AsyncFnOnce::async_call_once`]. |
| 46 | #[unstable (feature = "async_fn_traits" , issue = "none" )] |
| 47 | #[lang = "call_once_future" ] |
| 48 | type CallOnceFuture: Future<Output = Self::Output>; |
| 49 | |
| 50 | /// Output type of the called closure's future. |
| 51 | #[unstable (feature = "async_fn_traits" , issue = "none" )] |
| 52 | #[lang = "async_fn_once_output" ] |
| 53 | type Output; |
| 54 | |
| 55 | /// Call the [`AsyncFnOnce`], returning a future which may move out of the called closure. |
| 56 | #[unstable (feature = "async_fn_traits" , issue = "none" )] |
| 57 | extern "rust-call" fn async_call_once(self, args: Args) -> Self::CallOnceFuture; |
| 58 | } |
| 59 | |
| 60 | mod impls { |
| 61 | use super::{AsyncFn, AsyncFnMut, AsyncFnOnce}; |
| 62 | use crate::marker::Tuple; |
| 63 | |
| 64 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 65 | impl<A: Tuple, F: ?Sized> AsyncFn<A> for &F |
| 66 | where |
| 67 | F: AsyncFn<A>, |
| 68 | { |
| 69 | extern "rust-call" fn async_call(&self, args: A) -> Self::CallRefFuture<'_> { |
| 70 | F::async_call(*self, args) |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 75 | impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &F |
| 76 | where |
| 77 | F: AsyncFn<A>, |
| 78 | { |
| 79 | type CallRefFuture<'a> |
| 80 | = F::CallRefFuture<'a> |
| 81 | where |
| 82 | Self: 'a; |
| 83 | |
| 84 | extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallRefFuture<'_> { |
| 85 | F::async_call(*self, args) |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 90 | impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a F |
| 91 | where |
| 92 | F: AsyncFn<A>, |
| 93 | { |
| 94 | type Output = F::Output; |
| 95 | type CallOnceFuture = F::CallRefFuture<'a>; |
| 96 | |
| 97 | extern "rust-call" fn async_call_once(self, args: A) -> Self::CallOnceFuture { |
| 98 | F::async_call(self, args) |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 103 | impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &mut F |
| 104 | where |
| 105 | F: AsyncFnMut<A>, |
| 106 | { |
| 107 | type CallRefFuture<'a> |
| 108 | = F::CallRefFuture<'a> |
| 109 | where |
| 110 | Self: 'a; |
| 111 | |
| 112 | extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallRefFuture<'_> { |
| 113 | F::async_call_mut(*self, args) |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | #[stable (feature = "async_closure" , since = "1.85.0" )] |
| 118 | impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a mut F |
| 119 | where |
| 120 | F: AsyncFnMut<A>, |
| 121 | { |
| 122 | type Output = F::Output; |
| 123 | type CallOnceFuture = F::CallRefFuture<'a>; |
| 124 | |
| 125 | extern "rust-call" fn async_call_once(self, args: A) -> Self::CallOnceFuture { |
| 126 | F::async_call_mut(self, args) |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | mod internal_implementation_detail { |
| 132 | /// A helper trait that is used to enforce that the `ClosureKind` of a goal |
| 133 | /// is within the capabilities of a `CoroutineClosure`, and which allows us |
| 134 | /// to delay the projection of the tupled upvar types until after upvar |
| 135 | /// analysis is complete. |
| 136 | /// |
| 137 | /// The `Self` type is expected to be the `kind_ty` of the coroutine-closure, |
| 138 | /// and thus either `?0` or `i8`/`i16`/`i32` (see docs for `ClosureKind` |
| 139 | /// for an explanation of that). The `GoalKind` is also the same type, but |
| 140 | /// representing the kind of the trait that the closure is being called with. |
| 141 | #[lang = "async_fn_kind_helper" ] |
| 142 | trait AsyncFnKindHelper<GoalKind> { |
| 143 | // Projects a set of closure inputs (arguments), a region, and a set of upvars |
| 144 | // (by move and by ref) to the upvars that we expect the coroutine to have |
| 145 | // according to the `GoalKind` parameter above. |
| 146 | // |
| 147 | // The `Upvars` parameter should be the upvars of the parent coroutine-closure, |
| 148 | // and the `BorrowedUpvarsAsFnPtr` will be a function pointer that has the shape |
| 149 | // `for<'env> fn() -> (&'env T, ...)`. This allows us to represent the binder |
| 150 | // of the closure's self-capture, and these upvar types will be instantiated with |
| 151 | // the `'closure_env` region provided to the associated type. |
| 152 | #[lang = "async_fn_kind_upvars" ] |
| 153 | type Upvars<'closure_env, Inputs, Upvars, BorrowedUpvarsAsFnPtr>; |
| 154 | } |
| 155 | } |
| 156 | |