diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index 6b62236b32faf..40b35aa2324f3 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -1,5 +1,6 @@ #![stable(feature = "futures_api", since = "1.36.0")] +use crate::future::PollOnce; use crate::marker::Unpin; use crate::ops; use crate::pin::Pin; @@ -101,6 +102,32 @@ pub trait Future { #[lang = "poll"] #[stable(feature = "futures_api", since = "1.36.0")] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; + + /// Poll a future once. + /// + /// # Examples + /// + /// ```rust + /// #![feature(future_poll_once)] + /// + /// use std::future::{self, Future}; + /// use std::task::Poll; + /// + /// # let _ = async { + /// let f = future::ready(1); + /// assert_eq!(f.poll_once().await, Poll::Ready(1)); + /// + /// let mut f = future::pending::<()>(); + /// assert_eq!(f.poll_once().await, Poll::Pending); + /// # }; + /// ``` + #[unstable(feature = "future_poll_once", issue = "92115")] + fn poll_once(self) -> PollOnce + where + Self: Sized, + { + PollOnce { future: self } + } } #[stable(feature = "futures_api", since = "1.36.0")] diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index 7a3af70d6d97c..be29f7c0ad8b5 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -13,6 +13,7 @@ mod future; mod into_future; mod pending; mod poll_fn; +mod poll_once; mod ready; #[stable(feature = "futures_api", since = "1.36.0")] @@ -29,6 +30,9 @@ pub use ready::{ready, Ready}; #[unstable(feature = "future_poll_fn", issue = "72302")] pub use poll_fn::{poll_fn, PollFn}; +#[unstable(feature = "future_poll_once", issue = "92115")] +pub use poll_once::PollOnce; + /// 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/library/core/src/future/poll_once.rs b/library/core/src/future/poll_once.rs new file mode 100644 index 0000000000000..4360605b9d7c9 --- /dev/null +++ b/library/core/src/future/poll_once.rs @@ -0,0 +1,32 @@ +use crate::fmt; +use crate::future::Future; +use crate::pin::Pin; +use crate::task::{Context, Poll}; + +/// Resolves to the output of polling a future once. +/// +/// This `struct` is created by [`poll_once()`]. See its +/// documentation for more. +#[unstable(feature = "future_poll_once", issue = "92115")] +pub struct PollOnce { + pub(crate) future: F, +} + +#[unstable(feature = "future_poll_once", issue = "92115")] +impl fmt::Debug for PollOnce { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("PollOnce").finish() + } +} + +#[unstable(feature = "future_poll_once", issue = "92115")] +impl Future for PollOnce +where + F: Future + Unpin, +{ + type Output = Poll; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Poll::Ready(Pin::new(&mut self.future).poll(cx)) + } +}