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