1use crate::future::Future;
2use 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"]
12pub 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"]
26pub 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"]
46pub 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
60mod 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
125mod 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