@@ -213,7 +213,7 @@ impl<'a> Context<'a> {
213
213
#[ must_use]
214
214
#[ inline]
215
215
pub const fn from_waker ( waker : & ' a Waker ) -> Self {
216
- ContextBuilder :: new ( ) . waker ( waker) . build ( )
216
+ ContextBuilder :: from_waker ( waker) . build ( )
217
217
}
218
218
219
219
/// Returns a reference to the [`Waker`] for the current task.
@@ -261,28 +261,43 @@ impl fmt::Debug for Context<'_> {
261
261
/// let local_waker = LocalWaker::noop();
262
262
/// let waker = Waker::noop();
263
263
///
264
- /// let context = ContextBuilder::default()
265
- /// .local_waker(&local_waker)
264
+ /// let context = ContextBuilder::from_local_waker(&local_waker)
266
265
/// .waker(&waker)
267
266
/// .build();
267
+ ///
268
+ /// let future = pin::pin!(async { 20 });
269
+ /// let poll = future.poll(&mut context);
270
+ /// assert_eq!(poll, task::Poll::Ready(20));
271
+ ///
268
272
/// ```
269
273
#[ unstable( feature = "local_waker" , issue = "none" ) ]
270
- #[ derive( Default , Debug ) ]
274
+ #[ derive( Debug ) ]
271
275
pub struct ContextBuilder < ' a > {
272
276
waker : Option < & ' a Waker > ,
273
- local_waker : Option < & ' a LocalWaker > ,
277
+ local_waker : & ' a LocalWaker ,
274
278
}
275
279
276
280
impl < ' a > ContextBuilder < ' a > {
277
- /// Creates a new empty `ContextBuilder`.
281
+ /// Create a ContextBuilder from a Waker.
282
+ #[ inline]
283
+ #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
284
+ #[ unstable( feature = "local_waker" , issue = "none" ) ]
285
+ pub const fn from_waker ( waker : & ' a Waker ) -> Self {
286
+ // SAFETY: LocalWaker is just Waker without thread safety
287
+ let local_waker = unsafe { transmute ( waker) } ;
288
+ Self { waker : Some ( waker) , local_waker }
289
+ }
290
+
291
+ /// Create a ContextBuilder from a LocalWaker.
278
292
#[ inline]
279
293
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
280
294
#[ unstable( feature = "local_waker" , issue = "none" ) ]
281
- pub const fn new ( ) -> Self {
282
- ContextBuilder { waker : None , local_waker : None }
295
+ pub const fn from_local_waker ( local_waker : & ' a LocalWaker ) -> Self {
296
+ Self { local_waker , waker : None }
283
297
}
284
298
285
299
/// This field is used to set the value of the waker on `Context`.
300
+
286
301
#[ inline]
287
302
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
288
303
#[ unstable( feature = "local_waker" , issue = "none" ) ]
@@ -291,58 +306,19 @@ impl<'a> ContextBuilder<'a> {
291
306
}
292
307
293
308
/// This method is used to set the value for the local waker on `Context`.
294
- ///
295
- /// # Examples
296
- /// ```
297
- /// #![feature(local_waker)]
298
- /// #![feature(noop_waker)]
299
- ///
300
- /// use std::task;
301
- /// use std::pin;
302
- /// use std::future::Future;
303
- ///
304
- /// let local_waker = task::LocalWaker::noop();
305
- ///
306
- /// let mut context = task::ContextBuilder::new()
307
- /// .local_waker(&local_waker)
308
- /// .build();
309
- ///
310
- /// let future = pin::pin!(async { 20 });
311
- ///
312
- /// let poll = future.poll(&mut context);
313
- ///
314
- /// assert_eq!(poll, task::Poll::Ready(20));
315
- /// ```
316
309
#[ inline]
317
310
#[ unstable( feature = "local_waker" , issue = "none" ) ]
318
311
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
319
312
pub const fn local_waker ( self , local_waker : & ' a LocalWaker ) -> Self {
320
- Self { local_waker : Some ( local_waker ) , ..self }
313
+ Self { local_waker, ..self }
321
314
}
322
315
323
316
/// Builds the `Context`.
324
- ///
325
- /// # Panics
326
- /// Panics if no `Waker` or `LocalWaker` is set.
327
317
#[ inline]
328
318
#[ unstable( feature = "local_waker" , issue = "none" ) ]
329
319
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
330
320
pub const fn build ( self ) -> Context < ' a > {
331
321
let ContextBuilder { waker, local_waker } = self ;
332
- assert ! (
333
- waker. is_some( ) || local_waker. is_some( ) ,
334
- "at least one waker must be set with either the `local_waker` or `waker` methods on `ContextBuilder`."
335
- ) ;
336
- let local_waker = match local_waker {
337
- Some ( local_waker) => local_waker,
338
- None => {
339
- // SAFETY:
340
- // It is safe to transmute a `&Waker` into a `&LocalWaker` since both are a transparent
341
- // wrapper around a local waker. Also, the Option<&Waker> here cannot be None because
342
- // of the previous assert.
343
- unsafe { transmute ( self . waker ) }
344
- }
345
- } ;
346
322
Context { waker, local_waker, _marker : PhantomData , _marker2 : PhantomData }
347
323
}
348
324
}
@@ -549,8 +525,8 @@ impl fmt::Debug for Waker {
549
525
/// Local wakers can be requested from a `Context` with the [`local_waker`] method.
550
526
///
551
527
/// The typical life of a `LocalWaker` is that it is constructed by an executor, wrapped in a
552
- /// [`Context`], then passed to [`Future::poll()`]. Then, if the future chooses to return
553
- /// [`Poll::Pending`], it must also store the waker somehow and call [`Waker ::wake()`] when
528
+ /// [`Context`] using [`ContextBuilder`] , then passed to [`Future::poll()`]. Then, if the future chooses to return
529
+ /// [`Poll::Pending`], it must also store the waker somehow and call [`LocalWaker ::wake()`] when
554
530
/// the future should be polled again.
555
531
///
556
532
/// Implements [`Clone`], but neither [`Send`] nor [`Sync`]; therefore, a local waker may
@@ -564,7 +540,7 @@ impl fmt::Debug for Waker {
564
540
/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
565
541
///
566
542
/// # Examples
567
- ///
543
+ /// Usage of a local waker to implement a future
568
544
/// ```
569
545
/// #![feature(local_waker)]
570
546
/// use std::future::{Future, poll_fn};
@@ -582,12 +558,13 @@ impl fmt::Debug for Waker {
582
558
/// return Poll::Ready(())
583
559
/// })
584
560
/// }
561
+ ///
585
562
/// # #[allow(unused_must_use)]
586
563
/// # async fn __() {
587
564
/// yield_now().await;
588
565
/// # }
589
566
/// ```
590
- ///
567
+ ///
591
568
/// [`Future::poll()`]: core::future::Future::poll
592
569
/// [`Poll::Pending`]: core::task::Poll::Pending
593
570
/// [`local_waker`]: core::task::Context::local_waker
0 commit comments