@@ -217,7 +217,7 @@ impl RawWakerVTable {
217
217
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
218
218
#[ lang = "Context" ]
219
219
pub struct Context < ' a > {
220
- waker : Option < & ' a Waker > ,
220
+ waker : & ' a Waker ,
221
221
local_waker : & ' a LocalWaker ,
222
222
// Ensure we future-proof against variance changes by forcing
223
223
// the lifetime to be invariant (argument-position lifetimes
@@ -245,9 +245,7 @@ impl<'a> Context<'a> {
245
245
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
246
246
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
247
247
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
251
249
}
252
250
/// Returns a reference to the [`LocalWaker`] for the current task.
253
251
#[ inline]
@@ -256,14 +254,6 @@ impl<'a> Context<'a> {
256
254
pub const fn local_waker ( & self ) -> & ' a LocalWaker {
257
255
& self . local_waker
258
256
}
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
- }
267
257
}
268
258
269
259
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
@@ -286,8 +276,8 @@ impl fmt::Debug for Context<'_> {
286
276
/// let local_waker = LocalWaker::noop();
287
277
/// let waker = Waker::noop();
288
278
///
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 )
291
281
/// .build();
292
282
///
293
283
/// let mut future = std::pin::pin!(async { 20 });
@@ -298,8 +288,16 @@ impl fmt::Debug for Context<'_> {
298
288
#[ unstable( feature = "local_waker" , issue = "118959" ) ]
299
289
#[ derive( Debug ) ]
300
290
pub struct ContextBuilder < ' a > {
301
- waker : Option < & ' a Waker > ,
291
+ waker : & ' a Waker ,
302
292
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 ( ) > ,
303
301
}
304
302
305
303
impl < ' a > ContextBuilder < ' a > {
@@ -310,23 +308,7 @@ impl<'a> ContextBuilder<'a> {
310
308
pub const fn from_waker ( waker : & ' a Waker ) -> Self {
311
309
// SAFETY: LocalWaker is just Waker without thread safety
312
310
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 }
330
312
}
331
313
332
314
/// This method is used to set the value for the local waker on `Context`.
@@ -342,52 +324,8 @@ impl<'a> ContextBuilder<'a> {
342
324
#[ unstable( feature = "local_waker" , issue = "118959" ) ]
343
325
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
344
326
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 }
391
329
}
392
330
}
393
331
@@ -600,8 +538,7 @@ impl fmt::Debug for Waker {
600
538
/// Implements [`Clone`], but neither [`Send`] nor [`Sync`]; therefore, a local waker may
601
539
/// not be moved to other threads. In general, when deciding to use wakers or local wakers,
602
540
/// 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.
605
542
///
606
543
/// Note that it is preferable to use `local_waker.clone_from(&new_waker)` instead
607
544
/// of `*local_waker = new_waker.clone()`, as the former will avoid cloning the waker
@@ -738,7 +675,7 @@ impl LocalWaker {
738
675
/// use std::future::Future;
739
676
/// use std::task::{ContextBuilder, LocalWaker};
740
677
///
741
- /// let mut cx = task::ContextBuilder::new( )
678
+ /// let mut cx = task::ContextBuilder::from_waker(Waker::noop() )
742
679
/// .local_waker(LocalWaker::noop())
743
680
/// .build();
744
681
///
0 commit comments