Add AsyncFn family of traits
This commit is contained in:
parent
71696e516d
commit
0e6f7c6c7c
5 changed files with 134 additions and 1 deletions
|
@ -227,6 +227,7 @@
|
||||||
#![feature(fundamental)]
|
#![feature(fundamental)]
|
||||||
#![feature(generic_arg_infer)]
|
#![feature(generic_arg_infer)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
#![feature(inline_const)]
|
#![feature(inline_const)]
|
||||||
#![feature(intra_doc_pointers)]
|
#![feature(intra_doc_pointers)]
|
||||||
#![feature(intrinsics)]
|
#![feature(intrinsics)]
|
||||||
|
|
105
library/core/src/ops/async_function.rs
Normal file
105
library/core/src/ops/async_function.rs
Normal file
|
@ -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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -139,6 +139,7 @@
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
mod arith;
|
mod arith;
|
||||||
|
mod async_function;
|
||||||
mod bit;
|
mod bit;
|
||||||
mod control_flow;
|
mod control_flow;
|
||||||
mod coroutine;
|
mod coroutine;
|
||||||
|
@ -173,6 +174,9 @@ pub use self::drop::Drop;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::function::{Fn, FnMut, FnOnce};
|
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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::index::{Index, IndexMut};
|
pub use self::index::{Index, IndexMut};
|
||||||
|
|
||||||
|
|
16
tests/ui/async-await/async-fn/simple.rs
Normal file
16
tests/ui/async-await/async-fn/simple.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// edition: 2021
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(async_fn_traits)]
|
||||||
|
|
||||||
|
use std::ops::AsyncFn;
|
||||||
|
|
||||||
|
async fn foo() {}
|
||||||
|
|
||||||
|
async fn call_asyncly(f: impl AsyncFn(i32) -> i32) -> i32 {
|
||||||
|
f.async_call((1i32,)).await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let fut = call_asyncly(|x| async move { x + 1 });
|
||||||
|
}
|
|
@ -191,7 +191,14 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:33:10
|
--> $DIR/bad-assoc-ty.rs:33:10
|
||||||
|
|
|
|
||||||
LL | type H = Fn(u8) -> (u8)::Output;
|
LL | type H = Fn(u8) -> (u8)::Output;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output`
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: use fully-qualified syntax
|
||||||
|
|
|
||||||
|
LL | type H = <(dyn Fn(u8) -> u8 + 'static) as AsyncFnOnce>::Output;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
LL | type H = <(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:39:19
|
--> $DIR/bad-assoc-ty.rs:39:19
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue