core/ops/
async_function.rs

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#[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"]
11pub 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"]
24pub 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"]
44pub 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
60mod 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
131mod 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}