From a57c18b5e182f32218ace2620163d86b9412182d Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Thu, 7 Oct 2021 15:47:28 -0400 Subject: [PATCH 1/4] add `Poll::ready` --- library/core/src/task/mod.rs | 2 ++ library/core/src/task/poll.rs | 33 ++++++++++++++++++++ library/core/src/task/ready.rs | 57 ++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/library/core/src/task/mod.rs b/library/core/src/task/mod.rs index 5f077f77bbc9f..a872320aca65a 100644 --- a/library/core/src/task/mod.rs +++ b/library/core/src/task/mod.rs @@ -13,3 +13,5 @@ pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker}; mod ready; #[stable(feature = "ready_macro", since = "1.56.0")] pub use ready::ready; +#[unstable(feature = "poll_ready", issue = "none")] +pub use ready::Ready; diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 57416aeb7018f..924c424548fd1 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -3,6 +3,7 @@ use crate::convert; use crate::ops::{self, ControlFlow}; use crate::result::Result; +use crate::task::Ready; /// Indicates whether a value is available or if the current task has been /// scheduled to receive a wakeup instead. @@ -92,6 +93,38 @@ impl Poll { pub const fn is_pending(&self) -> bool { !self.is_ready() } + + /// Extracts the successful type of a [`Poll`]. + /// + /// When combined with the `?` operator, this function will + /// propogate any [`Poll::Pending`] values to the caller, and + /// extract the `T` from [`Poll::Ready`]. + /// + /// # Examples + /// + /// ```rust + /// #![feature(poll_ready)] + /// + /// use std::task::{Context, Poll}; + /// use std::future::{self, Future}; + /// use std::pin::Pin; + /// + /// pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> { + /// let mut fut = future::ready(42); + /// let fut = Pin::new(&mut fut); + /// + /// let num = fut.poll(cx).ready()?; + /// # drop(num); + /// // ... use num + /// + /// Poll::Ready(()) + /// } + /// ``` + #[inline] + #[unstable(feature = "poll_ready", issue = "none")] + pub fn ready(self) -> Ready { + Ready(self) + } } impl Poll> { diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs index 2834ca5fe2224..8b6e259134e7c 100644 --- a/library/core/src/task/ready.rs +++ b/library/core/src/task/ready.rs @@ -1,3 +1,8 @@ +use core::convert; +use core::fmt; +use core::ops::{ControlFlow, FromResidual, Try}; +use core::task::Poll; + /// Extracts the successful type of a [`Poll`]. /// /// This macro bakes in propagation of [`Pending`] signals by returning early. @@ -55,3 +60,55 @@ pub macro ready($e:expr) { } } } + +/// Extracts the successful type of a [`Poll`]. +/// +/// See [`Poll::ready`] for details. +#[unstable(feature = "poll_ready", issue = "none")] +pub struct Ready(pub(crate) Poll); + +#[unstable(feature = "poll_ready", issue = "none")] +impl Try for Ready { + type Output = T; + type Residual = Ready; + + #[inline] + fn from_output(output: Self::Output) -> Self { + Ready(Poll::Ready(output)) + } + + #[inline] + fn branch(self) -> ControlFlow { + match self.0 { + Poll::Ready(v) => ControlFlow::Continue(v), + Poll::Pending => ControlFlow::Break(Ready(Poll::Pending)), + } + } +} + +#[unstable(feature = "poll_ready", issue = "none")] +impl FromResidual for Ready { + #[inline] + fn from_residual(residual: Ready) -> Self { + match residual.0 { + Poll::Pending => Ready(Poll::Pending), + } + } +} + +#[unstable(feature = "poll_ready", issue = "none")] +impl FromResidual> for Poll { + #[inline] + fn from_residual(residual: Ready) -> Self { + match residual.0 { + Poll::Pending => Poll::Pending, + } + } +} + +#[unstable(feature = "poll_ready", issue = "none")] +impl fmt::Debug for Ready { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Ready").finish() + } +} From 5f7e7d2e93afd9478856d3dc026c6923a0f21641 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Thu, 7 Oct 2021 15:47:59 -0400 Subject: [PATCH 2/4] revert stabilization of `core::task::ready!` --- library/core/src/task/mod.rs | 2 +- library/core/src/task/ready.rs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/task/mod.rs b/library/core/src/task/mod.rs index a872320aca65a..b6128bb70c93c 100644 --- a/library/core/src/task/mod.rs +++ b/library/core/src/task/mod.rs @@ -11,7 +11,7 @@ mod wake; pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker}; mod ready; -#[stable(feature = "ready_macro", since = "1.56.0")] +#[unstable(feature = "ready_macro", issue = "70922")] pub use ready::ready; #[unstable(feature = "poll_ready", issue = "none")] pub use ready::Ready; diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs index 8b6e259134e7c..bb1b7ed6c6c05 100644 --- a/library/core/src/task/ready.rs +++ b/library/core/src/task/ready.rs @@ -13,6 +13,8 @@ use core::task::Poll; /// # Examples /// /// ``` +/// #![feature(ready_macro)] +/// /// use std::task::{ready, Context, Poll}; /// use std::future::{self, Future}; /// use std::pin::Pin; @@ -32,6 +34,7 @@ use core::task::Poll; /// The `ready!` call expands to: /// /// ``` +/// # #![feature(ready_macro)] /// # use std::task::{Context, Poll}; /// # use std::future::{self, Future}; /// # use std::pin::Pin; @@ -50,7 +53,7 @@ use core::task::Poll; /// # Poll::Ready(()) /// # } /// ``` -#[stable(feature = "ready_macro", since = "1.56.0")] +#[unstable(feature = "ready_macro", issue = "70922")] #[rustc_macro_transparency = "semitransparent"] pub macro ready($e:expr) { match $e { From 7a7dfa8b67364be9a6fcd0d5876ed1c55b55843b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 11 Oct 2021 12:06:32 -0700 Subject: [PATCH 3/4] Remove task::ready! from 1.56.0 release notes --- RELEASES.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index ef1377a4a32df..269740c171cfb 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -64,7 +64,6 @@ Stabilised APIs - [`VecDeque::shrink_to`] - [`HashMap::shrink_to`] - [`HashSet::shrink_to`] -- [`task::ready!`] These APIs are now usable in const contexts: @@ -128,7 +127,6 @@ and related tools. [`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to [`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to [`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to -[`task::ready!`]: https://doc.rust-lang.org/stable/std/task/macro.ready.html [`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html [`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first [`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first From a1e03fc563eaaab04b747cf8d3f1a0d8931e39fd Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 11 Oct 2021 12:17:41 -0700 Subject: [PATCH 4/4] Add library tracking issue for poll_ready feature --- library/core/src/task/mod.rs | 2 +- library/core/src/task/poll.rs | 2 +- library/core/src/task/ready.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/core/src/task/mod.rs b/library/core/src/task/mod.rs index b6128bb70c93c..71a67a2793a46 100644 --- a/library/core/src/task/mod.rs +++ b/library/core/src/task/mod.rs @@ -13,5 +13,5 @@ pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker}; mod ready; #[unstable(feature = "ready_macro", issue = "70922")] pub use ready::ready; -#[unstable(feature = "poll_ready", issue = "none")] +#[unstable(feature = "poll_ready", issue = "89780")] pub use ready::Ready; diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 924c424548fd1..3e0b3e89758a6 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -121,7 +121,7 @@ impl Poll { /// } /// ``` #[inline] - #[unstable(feature = "poll_ready", issue = "none")] + #[unstable(feature = "poll_ready", issue = "89780")] pub fn ready(self) -> Ready { Ready(self) } diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs index bb1b7ed6c6c05..174ca67546033 100644 --- a/library/core/src/task/ready.rs +++ b/library/core/src/task/ready.rs @@ -67,10 +67,10 @@ pub macro ready($e:expr) { /// Extracts the successful type of a [`Poll`]. /// /// See [`Poll::ready`] for details. -#[unstable(feature = "poll_ready", issue = "none")] +#[unstable(feature = "poll_ready", issue = "89780")] pub struct Ready(pub(crate) Poll); -#[unstable(feature = "poll_ready", issue = "none")] +#[unstable(feature = "poll_ready", issue = "89780")] impl Try for Ready { type Output = T; type Residual = Ready; @@ -89,7 +89,7 @@ impl Try for Ready { } } -#[unstable(feature = "poll_ready", issue = "none")] +#[unstable(feature = "poll_ready", issue = "89780")] impl FromResidual for Ready { #[inline] fn from_residual(residual: Ready) -> Self { @@ -99,7 +99,7 @@ impl FromResidual for Ready { } } -#[unstable(feature = "poll_ready", issue = "none")] +#[unstable(feature = "poll_ready", issue = "89780")] impl FromResidual> for Poll { #[inline] fn from_residual(residual: Ready) -> Self { @@ -109,7 +109,7 @@ impl FromResidual> for Poll { } } -#[unstable(feature = "poll_ready", issue = "none")] +#[unstable(feature = "poll_ready", issue = "89780")] impl fmt::Debug for Ready { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Ready").finish()