about summary refs log tree commit diff
path: root/library/core
diff options
context:
space:
mode:
Diffstat (limited to 'library/core')
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/ops/async_function.rs105
-rw-r--r--library/core/src/ops/mod.rs4
3 files changed, 110 insertions, 0 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 07720f23598..1cd0240b87c 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -227,6 +227,7 @@
 #![feature(fundamental)]
 #![feature(generic_arg_infer)]
 #![feature(if_let_guard)]
+#![feature(impl_trait_in_assoc_type)]
 #![feature(inline_const)]
 #![feature(intra_doc_pointers)]
 #![feature(intrinsics)]
diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs
new file mode 100644
index 00000000000..0e05badd06d
--- /dev/null
+++ b/library/core/src/ops/async_function.rs
@@ -0,0 +1,105 @@
+use crate::future::Future;
+use crate::marker::Tuple;
+
+/// An async-aware version of the [`Fn`](crate::ops::Fn) trait.
+///
+/// All `async fn` and functions returning futures implement this trait.
+#[unstable(feature = "async_fn_traits", issue = "none")]
+#[rustc_paren_sugar]
+#[fundamental]
+#[must_use = "async closures are lazy and do nothing unless called"]
+pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
+    /// Future returned by [`AsyncFn::async_call`].
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    type CallFuture<'a>: Future<Output = Self::Output>
+    where
+        Self: 'a;
+
+    /// Call the [`AsyncFn`], returning a future which may borrow from the called closure.
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    extern "rust-call" fn async_call(&self, args: Args) -> Self::CallFuture<'_>;
+}
+
+/// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait.
+///
+/// All `async fn` and functions returning futures implement this trait.
+#[unstable(feature = "async_fn_traits", issue = "none")]
+#[rustc_paren_sugar]
+#[fundamental]
+#[must_use = "async closures are lazy and do nothing unless called"]
+pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
+    /// Future returned by [`AsyncFnMut::async_call_mut`].
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    type CallMutFuture<'a>: Future<Output = Self::Output>
+    where
+        Self: 'a;
+
+    /// Call the [`AsyncFnMut`], returning a future which may borrow from the called closure.
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallMutFuture<'_>;
+}
+
+/// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait.
+///
+/// All `async fn` and functions returning futures implement this trait.
+#[unstable(feature = "async_fn_traits", issue = "none")]
+#[rustc_paren_sugar]
+#[fundamental]
+#[must_use = "async closures are lazy and do nothing unless called"]
+pub trait AsyncFnOnce<Args: Tuple> {
+    /// Future returned by [`AsyncFnOnce::async_call_once`].
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    type CallOnceFuture: Future<Output = Self::Output>;
+
+    /// Output type of the called closure's future.
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    type Output;
+
+    /// Call the [`AsyncFnOnce`], returning a future which may move out of the called closure.
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    extern "rust-call" fn async_call_once(self, args: Args) -> Self::CallOnceFuture;
+}
+
+mod impls {
+    use super::{AsyncFn, AsyncFnMut, AsyncFnOnce};
+    use crate::future::Future;
+    use crate::marker::Tuple;
+
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    impl<F: Fn<A>, A: Tuple> AsyncFn<A> for F
+    where
+        <F as FnOnce<A>>::Output: Future,
+    {
+        type CallFuture<'a> = impl Future<Output = Self::Output> where Self: 'a;
+
+        extern "rust-call" fn async_call(&self, args: A) -> Self::CallFuture<'_> {
+            async { self.call(args).await }
+        }
+    }
+
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    impl<F: FnMut<A>, A: Tuple> AsyncFnMut<A> for F
+    where
+        <F as FnOnce<A>>::Output: Future,
+    {
+        type CallMutFuture<'a> = impl Future<Output = Self::Output> where Self: 'a;
+
+        extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallMutFuture<'_> {
+            async { self.call_mut(args).await }
+        }
+    }
+
+    #[unstable(feature = "async_fn_traits", issue = "none")]
+    impl<F: FnOnce<A>, A: Tuple> AsyncFnOnce<A> for F
+    where
+        <F as FnOnce<A>>::Output: Future,
+    {
+        type CallOnceFuture = impl Future<Output = Self::Output>;
+
+        type Output = <<F as FnOnce<A>>::Output as Future>::Output;
+
+        extern "rust-call" fn async_call_once(self, args: A) -> Self::CallOnceFuture {
+            async { self.call_once(args).await }
+        }
+    }
+}
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index 35654d0b853..4289a86f89b 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -139,6 +139,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 mod arith;
+mod async_function;
 mod bit;
 mod control_flow;
 mod coroutine;
@@ -173,6 +174,9 @@ pub use self::drop::Drop;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::function::{Fn, FnMut, FnOnce};
 
+#[unstable(feature = "async_fn_traits", issue = "none")]
+pub use self::async_function::{AsyncFn, AsyncFnMut, AsyncFnOnce};
+
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::index::{Index, IndexMut};