From 029515d9164bddc0928c159d375aadfc7f256b28 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Mon, 6 Apr 2020 09:24:44 +0200 Subject: [PATCH] Add core::future::{pending,ready} --- src/libcore/future/mod.rs | 8 +++++ src/libcore/future/pending.rs | 57 +++++++++++++++++++++++++++++++++++ src/libcore/future/ready.rs | 45 +++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 src/libcore/future/pending.rs create mode 100644 src/libcore/future/ready.rs diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs index 8dfda7a4a32..d339e18d7c3 100644 --- a/src/libcore/future/mod.rs +++ b/src/libcore/future/mod.rs @@ -11,9 +11,17 @@ use crate::{ }; mod future; +mod pending; +mod ready; + #[stable(feature = "futures_api", since = "1.36.0")] pub use self::future::Future; +#[unstable(feature = "future_readiness_fns", issue = "70921")] +pub use pending::{pending, Pending}; +#[unstable(feature = "future_readiness_fns", issue = "70921")] +pub use ready::{ready, Ready}; + /// This type is needed because: /// /// a) Generators cannot implement `for<'a, 'b> Generator<&'a mut Context<'b>>`, so we need to pass diff --git a/src/libcore/future/pending.rs b/src/libcore/future/pending.rs new file mode 100644 index 00000000000..74887b68aa0 --- /dev/null +++ b/src/libcore/future/pending.rs @@ -0,0 +1,57 @@ +use crate::future::Future; +use crate::marker; +use crate::pin::Pin; +use crate::task::{Context, Poll}; + +/// Creates a future which never resolves, representing a computation that never +/// finishes. +/// +/// This `struct` is created by the [`pending`] function. See its +/// documentation for more. +/// +/// [`pending`]: fn.pending.html +#[unstable(feature = "future_readiness_fns", issue = "70921")] +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Pending { + _data: marker::PhantomData, +} + +/// Creates a future which never resolves, representing a computation that never +/// finishes. +/// +/// # Examples +/// +/// ```no_run +/// #![feature(future_readiness_fns)] +/// use core::future; +/// +/// # async fn run() { +/// let future = future::pending(); +/// let () = future.await; +/// unreachable!(); +/// # } +/// ``` +#[unstable(feature = "future_readiness_fns", issue = "70921")] +pub fn pending() -> Pending { + Pending { _data: marker::PhantomData } +} + +#[unstable(feature = "future_readiness_fns", issue = "70921")] +impl Future for Pending { + type Output = T; + + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { + Poll::Pending + } +} + +#[unstable(feature = "future_readiness_fns", issue = "70921")] +impl Unpin for Pending {} + +#[unstable(feature = "future_readiness_fns", issue = "70921")] +impl Clone for Pending { + fn clone(&self) -> Self { + pending() + } +} diff --git a/src/libcore/future/ready.rs b/src/libcore/future/ready.rs new file mode 100644 index 00000000000..31b39d7fb6c --- /dev/null +++ b/src/libcore/future/ready.rs @@ -0,0 +1,45 @@ +use crate::future::Future; +use crate::pin::Pin; +use crate::task::{Context, Poll}; + +/// Creates a future that is immediately ready with a value. +/// +/// This `struct` is created by the [`ready`] function. See its +/// documentation for more. +/// +/// [`ready`]: fn.ready.html +#[unstable(feature = "future_readiness_fns", issue = "70921")] +#[derive(Debug, Clone)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Ready(Option); + +#[unstable(feature = "future_readiness_fns", issue = "70921")] +impl Unpin for Ready {} + +#[unstable(feature = "future_readiness_fns", issue = "70921")] +impl Future for Ready { + type Output = T; + + #[inline] + fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + Poll::Ready(self.0.take().expect("Ready polled after completion")) + } +} + +/// Creates a future that is immediately ready with a value. +/// +/// # Examples +/// +/// ``` +/// #![feature(future_readiness_fns)] +/// use core::future; +/// +/// # async fn run() { +/// let a = future::ready(1); +/// assert_eq!(a.await, 1); +/// # } +/// ``` +#[unstable(feature = "future_readiness_fns", issue = "70921")] +pub fn ready(t: T) -> Ready { + Ready(Some(t)) +}