@@ -213,7 +213,7 @@ impl<'a> Context<'a> {
213213 #[ must_use]
214214 #[ inline]
215215 pub const fn from_waker ( waker : & ' a Waker ) -> Self {
216- ContextBuilder :: new ( ) . waker ( waker) . build ( )
216+ ContextBuilder :: from_waker ( waker) . build ( )
217217 }
218218
219219 /// Returns a reference to the [`Waker`] for the current task.
@@ -261,28 +261,43 @@ impl fmt::Debug for Context<'_> {
261261/// let local_waker = LocalWaker::noop();
262262/// let waker = Waker::noop();
263263///
264- /// let context = ContextBuilder::default()
265- /// .local_waker(&local_waker)
264+ /// let context = ContextBuilder::from_local_waker(&local_waker)
266265/// .waker(&waker)
267266/// .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+ ///
268272/// ```
269273#[ unstable( feature = "local_waker" , issue = "none" ) ]
270- #[ derive( Default , Debug ) ]
274+ #[ derive( Debug ) ]
271275pub struct ContextBuilder < ' a > {
272276 waker : Option < & ' a Waker > ,
273- local_waker : Option < & ' a LocalWaker > ,
277+ local_waker : & ' a LocalWaker ,
274278}
275279
276280impl < ' 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.
278292 #[ inline]
279293 #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
280294 #[ 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 }
283297 }
284298
285299 /// This field is used to set the value of the waker on `Context`.
300+
286301 #[ inline]
287302 #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
288303 #[ unstable( feature = "local_waker" , issue = "none" ) ]
@@ -291,58 +306,19 @@ impl<'a> ContextBuilder<'a> {
291306 }
292307
293308 /// 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- /// ```
316309 #[ inline]
317310 #[ unstable( feature = "local_waker" , issue = "none" ) ]
318311 #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
319312 pub const fn local_waker ( self , local_waker : & ' a LocalWaker ) -> Self {
320- Self { local_waker : Some ( local_waker ) , ..self }
313+ Self { local_waker, ..self }
321314 }
322315
323316 /// Builds the `Context`.
324- ///
325- /// # Panics
326- /// Panics if no `Waker` or `LocalWaker` is set.
327317 #[ inline]
328318 #[ unstable( feature = "local_waker" , issue = "none" ) ]
329319 #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
330320 pub const fn build ( self ) -> Context < ' a > {
331321 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- } ;
346322 Context { waker, local_waker, _marker : PhantomData , _marker2 : PhantomData }
347323 }
348324}
@@ -549,8 +525,8 @@ impl fmt::Debug for Waker {
549525/// Local wakers can be requested from a `Context` with the [`local_waker`] method.
550526///
551527/// 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
554530/// the future should be polled again.
555531///
556532/// Implements [`Clone`], but neither [`Send`] nor [`Sync`]; therefore, a local waker may
@@ -564,7 +540,7 @@ impl fmt::Debug for Waker {
564540/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
565541///
566542/// # Examples
567- ///
543+ /// Usage of a local waker to implement a future
568544/// ```
569545/// #![feature(local_waker)]
570546/// use std::future::{Future, poll_fn};
@@ -582,12 +558,13 @@ impl fmt::Debug for Waker {
582558/// return Poll::Ready(())
583559/// })
584560/// }
561+ ///
585562/// # #[allow(unused_must_use)]
586563/// # async fn __() {
587564/// yield_now().await;
588565/// # }
589566/// ```
590- ///
567+ ///
591568/// [`Future::poll()`]: core::future::Future::poll
592569/// [`Poll::Pending`]: core::task::Poll::Pending
593570/// [`local_waker`]: core::task::Context::local_waker
0 commit comments