Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 232cc2b

Browse files
committed
refactor: remove in favor of and to make the API infallible.
1 parent 0cb5e2f commit 232cc2b

File tree

1 file changed

+29
-52
lines changed

1 file changed

+29
-52
lines changed

library/core/src/task/wake.rs

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
271275
pub struct ContextBuilder<'a> {
272276
waker: Option<&'a Waker>,
273-
local_waker: Option<&'a LocalWaker>,
277+
local_waker: &'a LocalWaker,
274278
}
275279

276280
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.
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

Comments
 (0)