@@ -225,21 +225,32 @@ impl<'a> Context<'a> {
225225 /// # Panics
226226 /// This function will panic if no `Waker` was set on the context. This happens if
227227 /// the executor does not support working with thread safe wakers. An alternative
228- /// may be to call [`.local_waker()`](Context::local_waker) instead.
228+ /// may be to call [`.local_waker()`](Context::local_waker) instead. For a fallible
229+ /// version of this function see [`.try_waker()`](Context::try_waker).
230+ #[ inline]
231+ #[ must_use]
229232 #[ stable( feature = "futures_api" , since = "1.36.0" ) ]
230233 #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
231- #[ must_use]
232- #[ inline]
233234 pub const fn waker ( & self ) -> & ' a Waker {
234235 & self
235236 . waker
236237 . expect ( "no waker was set on this context, consider calling `local_waker` instead." )
237238 }
238239 /// Returns a reference to the [`LocalWaker`] for the current task.
240+ #[ inline]
239241 #[ unstable( feature = "local_waker" , issue = "none" ) ]
240- pub fn local_waker ( & self ) -> & ' a LocalWaker {
242+ #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
243+ pub const fn local_waker ( & self ) -> & ' a LocalWaker {
241244 & self . local_waker
242245 }
246+ /// Returns a `Some(&Waker)` if a waker was defined on the `Context`,
247+ /// otherwise it returns `None`.
248+ #[ inline]
249+ #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
250+ #[ unstable( feature = "local_waker" , issue = "none" ) ]
251+ pub const fn try_waker ( & self ) -> Option < & ' a Waker > {
252+ self . waker
253+ }
243254}
244255
245256#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
@@ -256,18 +267,19 @@ impl fmt::Debug for Context<'_> {
256267/// ```
257268/// #![feature(local_waker)]
258269/// #![feature(noop_waker)]
259- /// use std::task::{ContextBuilder, LocalWaker, Waker};
260- ///
270+ /// use std::task::{ContextBuilder, LocalWaker, Waker, Poll};
271+ /// use std::future::Future;
272+ ///
261273/// let local_waker = LocalWaker::noop();
262274/// let waker = Waker::noop();
263275///
264- /// let context = ContextBuilder::from_local_waker(&local_waker)
276+ /// let mut cx = ContextBuilder::from_local_waker(&local_waker)
265277/// .waker(&waker)
266278/// .build();
267279///
268- /// let future = pin::pin!(async { 20 });
269- /// let poll = future.poll(&mut context );
270- /// assert_eq!(poll, task:: Poll::Ready(20));
280+ /// let mut future = std:: pin::pin!(async { 20 });
281+ /// let poll = future.as_mut(). poll(&mut cx );
282+ /// assert_eq!(poll, Poll::Ready(20));
271283///
272284/// ```
273285#[ unstable( feature = "local_waker" , issue = "none" ) ]
@@ -323,6 +335,50 @@ impl<'a> ContextBuilder<'a> {
323335 }
324336}
325337
338+ /// Construct a `ContextBuilder`` from a `Context`. This is useful for
339+ /// overriding values from a context.
340+ ///
341+ /// # Examples
342+ /// An example of a future that allows to set a Waker on Context if none was defined.
343+ /// This can be used to await futures that require a `Waker` even if the runtime does not
344+ /// support `Waker`.
345+ /// ```rust
346+ /// #![feature(noop_waker, local_waker)]
347+ /// use std::task::{Waker, ContextBuilder};
348+ /// use std::future::{poll_fn, Future};
349+ /// use std::pin::pin;
350+ ///
351+ /// async fn with_waker<F>(f: F, waker: &Waker) -> F::Output
352+ /// where
353+ /// F: Future
354+ /// {
355+ /// let mut f = pin!(f);
356+ /// poll_fn(move |cx| {
357+ /// let has_waker = cx.try_waker().is_some();
358+ /// if has_waker {
359+ /// return f.as_mut().poll(cx);
360+ /// }
361+ ///
362+ /// let mut cx = ContextBuilder::from(cx)
363+ /// .waker(&waker)
364+ /// .build();
365+ /// f.as_mut().poll(&mut cx)
366+ /// }).await
367+ /// }
368+ ///
369+ /// # async fn __() {
370+ /// with_waker(async { /* ... */ }, &Waker::noop()).await;
371+ /// # }
372+ /// ```
373+ #[ unstable( feature = "local_waker" , issue = "none" ) ]
374+ impl < ' a > From < & mut Context < ' a > > for ContextBuilder < ' a > {
375+ #[ inline]
376+ fn from ( value : & mut Context < ' a > ) -> Self {
377+ let Context { waker, local_waker, .. } = * value;
378+ ContextBuilder { waker, local_waker }
379+ }
380+ }
381+
326382/// A `Waker` is a handle for waking up a task by notifying its executor that it
327383/// is ready to be run.
328384///
@@ -559,12 +615,11 @@ impl fmt::Debug for Waker {
559615/// })
560616/// }
561617///
562- /// # #[allow(unused_must_use)]
563618/// # async fn __() {
564619/// yield_now().await;
565620/// # }
566621/// ```
567- ///
622+ ///
568623/// [`Future::poll()`]: core::future::Future::poll
569624/// [`Poll::Pending`]: core::task::Poll::Pending
570625/// [`local_waker`]: core::task::Context::local_waker
0 commit comments