@@ -217,7 +217,7 @@ impl RawWakerVTable {
217217#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
218218#[ lang = "Context" ]
219219pub struct Context < ' a > {
220- waker : Option < & ' a Waker > ,
220+ waker : & ' a Waker ,
221221 local_waker : & ' a LocalWaker ,
222222 // Ensure we future-proof against variance changes by forcing
223223 // the lifetime to be invariant (argument-position lifetimes
@@ -245,9 +245,7 @@ impl<'a> Context<'a> {
245245 #[ stable( feature = "futures_api" , since = "1.36.0" ) ]
246246 #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
247247 pub const fn waker ( & self ) -> & ' a Waker {
248- & self
249- . waker
250- . expect ( "no waker was set on this context, consider calling `local_waker` instead." )
248+ & self . waker
251249 }
252250 /// Returns a reference to the [`LocalWaker`] for the current task.
253251 #[ inline]
@@ -256,14 +254,6 @@ impl<'a> Context<'a> {
256254 pub const fn local_waker ( & self ) -> & ' a LocalWaker {
257255 & self . local_waker
258256 }
259- /// Returns a `Some(&Waker)` if a waker was defined on the `Context`,
260- /// otherwise it returns `None`.
261- #[ inline]
262- #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
263- #[ unstable( feature = "local_waker" , issue = "118959" ) ]
264- pub const fn try_waker ( & self ) -> Option < & ' a Waker > {
265- self . waker
266- }
267257}
268258
269259#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
@@ -286,8 +276,8 @@ impl fmt::Debug for Context<'_> {
286276/// let local_waker = LocalWaker::noop();
287277/// let waker = Waker::noop();
288278///
289- /// let mut cx = ContextBuilder::from_local_waker(&local_waker )
290- /// .waker(&waker )
279+ /// let mut cx = ContextBuilder::from_waker(&waker )
280+ /// .local_waker(&local_waker )
291281/// .build();
292282///
293283/// let mut future = std::pin::pin!(async { 20 });
@@ -298,8 +288,16 @@ impl fmt::Debug for Context<'_> {
298288#[ unstable( feature = "local_waker" , issue = "118959" ) ]
299289#[ derive( Debug ) ]
300290pub struct ContextBuilder < ' a > {
301- waker : Option < & ' a Waker > ,
291+ waker : & ' a Waker ,
302292 local_waker : & ' a LocalWaker ,
293+ // Ensure we future-proof against variance changes by forcing
294+ // the lifetime to be invariant (argument-position lifetimes
295+ // are contravariant while return-position lifetimes are
296+ // covariant).
297+ _marker : PhantomData < fn ( & ' a ( ) ) -> & ' a ( ) > ,
298+ // Ensure `Context` is `!Send` and `!Sync` in order to allow
299+ // for future `!Send` and / or `!Sync` fields.
300+ _marker2 : PhantomData < * mut ( ) > ,
303301}
304302
305303impl < ' a > ContextBuilder < ' a > {
@@ -310,23 +308,7 @@ impl<'a> ContextBuilder<'a> {
310308 pub const fn from_waker ( waker : & ' a Waker ) -> Self {
311309 // SAFETY: LocalWaker is just Waker without thread safety
312310 let local_waker = unsafe { transmute ( waker) } ;
313- Self { waker : Some ( waker) , local_waker }
314- }
315-
316- /// Create a ContextBuilder from a LocalWaker.
317- #[ inline]
318- #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
319- #[ unstable( feature = "local_waker" , issue = "118959" ) ]
320- pub const fn from_local_waker ( local_waker : & ' a LocalWaker ) -> Self {
321- Self { local_waker, waker : None }
322- }
323-
324- /// This field is used to set the value of the waker on `Context`.
325- #[ inline]
326- #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
327- #[ unstable( feature = "local_waker" , issue = "118959" ) ]
328- pub const fn waker ( self , waker : & ' a Waker ) -> Self {
329- Self { waker : Some ( waker) , ..self }
311+ Self { waker : waker, local_waker, _marker : PhantomData , _marker2 : PhantomData }
330312 }
331313
332314 /// This method is used to set the value for the local waker on `Context`.
@@ -342,52 +324,8 @@ impl<'a> ContextBuilder<'a> {
342324 #[ unstable( feature = "local_waker" , issue = "118959" ) ]
343325 #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
344326 pub const fn build ( self ) -> Context < ' a > {
345- let ContextBuilder { waker, local_waker } = self ;
346- Context { waker, local_waker, _marker : PhantomData , _marker2 : PhantomData }
347- }
348- }
349-
350- /// Construct a [`ContextBuilder`] from a [`Context`]. This is useful for
351- /// overriding values from a context.
352- ///
353- /// # Examples
354- /// An example of a future that allows to set a [`Waker`] on Context if none was defined.
355- /// This can be used to await futures that require a [`Waker`] even if the runtime does not
356- /// support [`Waker`].
357- /// ```rust
358- /// #![feature(noop_waker, local_waker)]
359- /// use std::task::{Waker, ContextBuilder};
360- /// use std::future::{poll_fn, Future};
361- /// use std::pin::pin;
362- ///
363- /// async fn with_waker<F>(f: F, waker: &Waker) -> F::Output
364- /// where
365- /// F: Future
366- /// {
367- /// let mut f = pin!(f);
368- /// poll_fn(move |cx| {
369- /// let has_waker = cx.try_waker().is_some();
370- /// if has_waker {
371- /// return f.as_mut().poll(cx);
372- /// }
373- ///
374- /// let mut cx = ContextBuilder::from(cx)
375- /// .waker(&waker)
376- /// .build();
377- /// f.as_mut().poll(&mut cx)
378- /// }).await
379- /// }
380- ///
381- /// # async fn __() {
382- /// with_waker(async { /* ... */ }, &Waker::noop()).await;
383- /// # }
384- /// ```
385- #[ unstable( feature = "local_waker" , issue = "118959" ) ]
386- impl < ' a > From < & mut Context < ' a > > for ContextBuilder < ' a > {
387- #[ inline]
388- fn from ( value : & mut Context < ' a > ) -> Self {
389- let Context { waker, local_waker, _marker, _marker2 } = * value;
390- ContextBuilder { waker, local_waker }
327+ let ContextBuilder { waker, local_waker, _marker, _marker2 } = self ;
328+ Context { waker, local_waker, _marker, _marker2 }
391329 }
392330}
393331
@@ -600,8 +538,7 @@ impl fmt::Debug for Waker {
600538/// Implements [`Clone`], but neither [`Send`] nor [`Sync`]; therefore, a local waker may
601539/// not be moved to other threads. In general, when deciding to use wakers or local wakers,
602540/// local wakers are preferable unless the waker needs to be sent across threads. This is because
603- /// wakers can incur in additional cost related to memory synchronization, and not all executors
604- /// may support wakers.
541+ /// wakers can incur in additional cost related to memory synchronization.
605542///
606543/// Note that it is preferable to use `local_waker.clone_from(&new_waker)` instead
607544/// of `*local_waker = new_waker.clone()`, as the former will avoid cloning the waker
@@ -738,7 +675,7 @@ impl LocalWaker {
738675 /// use std::future::Future;
739676 /// use std::task::{ContextBuilder, LocalWaker};
740677 ///
741- /// let mut cx = task::ContextBuilder::new( )
678+ /// let mut cx = task::ContextBuilder::from_waker(Waker::noop() )
742679 /// .local_waker(LocalWaker::noop())
743680 /// .build();
744681 ///
0 commit comments