async_lock/once_cell.rs
1use core::cell::UnsafeCell;
2use core::convert::Infallible;
3use core::fmt;
4use core::future::Future;
5use core::mem::{forget, MaybeUninit};
6use core::ptr;
7
8use crate::sync::atomic::{AtomicUsize, Ordering};
9
10#[cfg(not(loom))]
11use crate::sync::WithMut;
12
13use event_listener::Event;
14use event_listener_strategy::{NonBlocking, Strategy};
15
16#[cfg(all(feature = "std", not(target_family = "wasm")))]
17use event_listener::Listener;
18
19/// The current state of the `OnceCell`.
20#[derive(Copy, Clone, PartialEq, Eq)]
21#[repr(usize)]
22enum State {
23 /// The `OnceCell` is uninitialized.
24 Uninitialized = 0,
25 /// The `OnceCell` is being initialized.
26 Initializing = 1,
27 /// The `OnceCell` is initialized.
28 Initialized = 2,
29}
30
31impl From<usize> for State {
32 fn from(val: usize) -> Self {
33 match val {
34 0 => State::Uninitialized,
35 1 => State::Initializing,
36 2 => State::Initialized,
37 _ => unreachable!("Invalid state"),
38 }
39 }
40}
41
42impl From<State> for usize {
43 fn from(val: State) -> Self {
44 val as usize
45 }
46}
47
48/// A memory location that can be written to at most once.
49///
50/// A `OnceCell` can be used to store a single value, and only once. However,
51/// once the value is stored, it can be accessed directly through a reference
52/// instead of needing an RAII guard like `Mutex` or `RwLock`.
53///
54/// # Examples
55///
56/// This structure is useful for a variety of patterns, most notably for one-time
57/// initialization.
58///
59/// ```rust
60/// use async_lock::OnceCell;
61///
62/// # struct Foobar;
63///
64/// async fn very_expensive_initialization() -> Foobar {
65/// // Imagine this is very expensive to initialize,
66/// // for instance, it requires a network request or
67/// // a database call.
68/// # Foobar
69/// }
70///
71/// struct LazyFoobar {
72/// inner: OnceCell<Foobar>,
73/// }
74///
75/// impl LazyFoobar {
76/// fn new() -> Self {
77/// Self {
78/// inner: OnceCell::new(),
79/// }
80/// }
81///
82/// async fn load(&self) -> &Foobar {
83/// self.inner.get_or_init(|| async {
84/// very_expensive_initialization().await
85/// }).await
86/// }
87/// }
88/// ```
89pub struct OnceCell<T> {
90 /// Listeners waiting for a chance to initialize the cell.
91 ///
92 /// These are the users of get_or_init() and similar functions.
93 active_initializers: Event,
94
95 /// Listeners waiting for the cell to be initialized.
96 ///
97 /// These are the users of wait().
98 passive_waiters: Event,
99
100 /// State associated with the cell.
101 state: AtomicUsize,
102
103 /// The value of the cell.
104 value: UnsafeCell<MaybeUninit<T>>,
105}
106
107unsafe impl<T: Send> Send for OnceCell<T> {}
108unsafe impl<T: Send + Sync> Sync for OnceCell<T> {}
109
110impl<T> OnceCell<T> {
111 const_fn! {
112 const_if: #[cfg(not(loom))];
113 /// Create a new, uninitialized `OnceCell`.
114 ///
115 /// # Example
116 ///
117 /// ```rust
118 /// use async_lock::OnceCell;
119 ///
120 /// let cell = OnceCell::new();
121 /// # let _: Option<&u32> = cell.get();
122 /// ```
123 pub const fn new() -> Self {
124 Self {
125 active_initializers: Event::new(),
126 passive_waiters: Event::new(),
127 state: AtomicUsize::new(State::Uninitialized as _),
128 value: UnsafeCell::new(MaybeUninit::uninit()),
129 }
130 }
131 }
132
133 /// Tell whether or not the cell is initialized.
134 ///
135 /// This may not always be accurate. For instance, it is possible for
136 /// another thread to initialize the cell between the time when this
137 /// function is called and the time when the result is actually used.
138 ///
139 /// # Example
140 ///
141 /// ```rust
142 /// use async_lock::OnceCell;
143 ///
144 /// # futures_lite::future::block_on(async {
145 /// let cell = OnceCell::new();
146 /// assert!(!cell.is_initialized());
147 /// cell.set(1).await;
148 /// assert!(cell.is_initialized());
149 /// # });
150 /// ```
151 pub fn is_initialized(&self) -> bool {
152 State::from(self.state.load(Ordering::Acquire)) == State::Initialized
153 }
154
155 /// Get a reference to the inner value, or `None` if the value
156 /// is not yet initialized.
157 ///
158 /// # Example
159 ///
160 /// ```rust
161 /// use async_lock::OnceCell;
162 ///
163 /// # futures_lite::future::block_on(async {
164 /// let cell = OnceCell::new();
165 /// assert!(cell.get().is_none());
166 /// cell.set(1).await;
167 /// assert_eq!(cell.get(), Some(&1));
168 /// # });
169 /// ```
170 pub fn get(&self) -> Option<&T> {
171 if self.is_initialized() {
172 // SAFETY: We know that the value is initialized, so it is safe to
173 // read it.
174 Some(unsafe { self.get_unchecked() })
175 } else {
176 None
177 }
178 }
179
180 /// Get a mutable reference to the inner value, or `None` if the value
181 /// is not yet initialized.
182 ///
183 /// This function is useful for initializing the value inside the cell
184 /// when we still have a mutable reference to the cell.
185 ///
186 /// # Example
187 ///
188 /// ```rust
189 /// use async_lock::OnceCell;
190 ///
191 /// # futures_lite::future::block_on(async {
192 /// let mut cell = OnceCell::new();
193 /// assert!(cell.get_mut().is_none());
194 /// cell.set(1).await;
195 /// assert_eq!(cell.get_mut(), Some(&mut 1));
196 /// *cell.get_mut().unwrap() = 2;
197 /// assert_eq!(cell.get(), Some(&2));
198 /// # });
199 /// ```
200 pub fn get_mut(&mut self) -> Option<&mut T> {
201 self.state.with_mut(|state| {
202 if State::from(*state) == State::Initialized {
203 // SAFETY: We know that the value is initialized, so it is safe to
204 // read it.
205 Some(unsafe { &mut *self.value.get().cast() })
206 } else {
207 None
208 }
209 })
210 }
211
212 /// Take the value out of this `OnceCell`, moving it back to the uninitialized
213 /// state.
214 ///
215 /// # Example
216 ///
217 /// ```rust
218 /// use async_lock::OnceCell;
219 ///
220 /// # futures_lite::future::block_on(async {
221 /// let mut cell = OnceCell::new();
222 /// cell.set(1).await;
223 /// assert_eq!(cell.take(), Some(1));
224 /// assert!(!cell.is_initialized());
225 /// # });
226 /// ```
227 pub fn take(&mut self) -> Option<T> {
228 self.state.with_mut(|state| {
229 if State::from(*state) == State::Initialized {
230 // SAFETY: We know that the value is initialized, so it is safe to
231 // read it.
232 let value = unsafe { ptr::read(self.value.get().cast()) };
233 *state = State::Uninitialized.into();
234 Some(value)
235 } else {
236 None
237 }
238 })
239 }
240
241 /// Convert this `OnceCell` into the inner value, if it is initialized.
242 ///
243 /// # Example
244 ///
245 /// ```rust
246 /// use async_lock::OnceCell;
247 ///
248 /// # futures_lite::future::block_on(async {
249 /// let cell = OnceCell::new();
250 /// cell.set(1).await;
251 /// assert_eq!(cell.into_inner(), Some(1));
252 /// # });
253 /// ```
254 pub fn into_inner(mut self) -> Option<T> {
255 self.take()
256 }
257
258 /// Wait for the cell to be initialized, and then return a reference to the
259 /// inner value.
260 ///
261 /// # Example
262 ///
263 #[cfg_attr(not(target_family = "wasm"), doc = "```rust")]
264 #[cfg_attr(target_family = "wasm", doc = "```ignore")]
265 /// use async_lock::OnceCell;
266 /// use std::sync::Arc;
267 /// use std::time::Duration;
268 /// use std::thread::{sleep, spawn};
269 ///
270 /// let cell = Arc::new(OnceCell::new());
271 /// let cell2 = cell.clone();
272 ///
273 /// spawn(move || {
274 /// sleep(Duration::from_millis(5));
275 /// cell2.set_blocking(1);
276 /// });
277 ///
278 /// # futures_lite::future::block_on(async {
279 /// assert_eq!(cell.wait().await, &1);
280 /// # });
281 /// ```
282 pub async fn wait(&self) -> &T {
283 // Fast path: see if the value is already initialized.
284 if let Some(value) = self.get() {
285 return value;
286 }
287
288 // Slow path: wait for the value to be initialized.
289 event_listener::listener!(self.passive_waiters => listener);
290
291 // Try again.
292 if let Some(value) = self.get() {
293 return value;
294 }
295
296 listener.await;
297 debug_assert!(self.is_initialized());
298
299 // SAFETY: We know that the value is initialized, so it is safe to
300 // read it.
301 unsafe { self.get_unchecked() }
302 }
303
304 /// Wait for the cell to be initialized, and then return a reference to the
305 /// inner value.
306 ///
307 /// # Blocking
308 ///
309 /// In contrast to the `wait` method, this method blocks the current thread of
310 /// execution instead of awaiting.
311 ///
312 /// This method should not be used in an asynchronous context. It is intended
313 /// to be used such that a `OnceCell` can be used in both asynchronous and synchronous contexts.
314 /// Calling this method in an asynchronous context may result in deadlocks.
315 ///
316 /// # Example
317 ///
318 /// ```rust
319 /// use async_lock::OnceCell;
320 /// use std::sync::Arc;
321 /// use std::time::Duration;
322 /// use std::thread::{sleep, spawn};
323 ///
324 /// let cell = Arc::new(OnceCell::new());
325 /// let cell2 = cell.clone();
326 ///
327 /// spawn(move || {
328 /// sleep(Duration::from_millis(5));
329 /// cell2.set_blocking(1);
330 /// });
331 ///
332 /// assert_eq!(cell.wait_blocking(), &1);
333 /// ```
334 #[cfg(all(feature = "std", not(target_family = "wasm")))]
335 pub fn wait_blocking(&self) -> &T {
336 // Fast path: see if the value is already initialized.
337 if let Some(value) = self.get() {
338 return value;
339 }
340
341 // Slow path: wait for the value to be initialized.
342 event_listener::listener!(self.passive_waiters => listener);
343
344 // Try again.
345 if let Some(value) = self.get() {
346 return value;
347 }
348
349 listener.wait();
350 debug_assert!(self.is_initialized());
351
352 // SAFETY: We know that the value is initialized, so it is safe to
353 // read it.
354 unsafe { self.get_unchecked() }
355 }
356
357 /// Either get the value or initialize it with the given closure.
358 ///
359 /// The cell will not be initialized if the closure returns an error.
360 ///
361 /// # Example
362 ///
363 /// ```rust
364 /// use async_lock::OnceCell;
365 /// #
366 /// # // Prevent explicit value errors.
367 /// # fn _explicit(_: &Result<&i32, ()>) {}
368 ///
369 /// # futures_lite::future::block_on(async {
370 /// let cell = OnceCell::new();
371 ///
372 /// let result = cell.get_or_try_init(|| async { Err(()) }).await;
373 /// assert!(result.is_err());
374 ///
375 /// let result = cell.get_or_try_init(|| async { Ok(1) }).await;
376 /// # _explicit(&result);
377 /// assert_eq!(result.unwrap(), &1);
378 ///
379 /// let result = cell.get_or_try_init(|| async { Err(()) }).await;
380 ///
381 /// assert_eq!(result.unwrap(), &1);
382 /// # });
383 /// ```
384 pub async fn get_or_try_init<E, Fut: Future<Output = Result<T, E>>>(
385 &self,
386 closure: impl FnOnce() -> Fut,
387 ) -> Result<&T, E> {
388 // Fast path: see if the value is already initialized.
389 if let Some(value) = self.get() {
390 return Ok(value);
391 }
392
393 // Slow path: initialize the value.
394 self.initialize_or_wait(closure, &mut NonBlocking::default())
395 .await?;
396 debug_assert!(self.is_initialized());
397
398 // SAFETY: We know that the value is initialized, so it is safe to
399 // read it.
400 Ok(unsafe { self.get_unchecked() })
401 }
402
403 /// Either get the value or initialize it with the given closure.
404 ///
405 /// The cell will not be initialized if the closure returns an error.
406 ///
407 /// # Blocking
408 ///
409 /// In contrast to the `get_or_try_init` method, this method blocks the current thread of
410 /// execution instead of awaiting.
411 ///
412 /// This method should not be used in an asynchronous context. It is intended
413 /// to be used such that a `OnceCell` can be used in both asynchronous and synchronous contexts.
414 /// Calling this method in an asynchronous context may result in deadlocks.
415 ///
416 /// # Example
417 ///
418 /// ```rust
419 /// use async_lock::OnceCell;
420 /// #
421 /// # // Prevent explicit type errors.
422 /// # fn _explicit(_: &Result<&i32, ()>) {}
423 ///
424 /// let cell = OnceCell::new();
425 ///
426 /// let result = cell.get_or_try_init_blocking(|| Err(()));
427 /// assert!(result.is_err());
428 ///
429 /// let result = cell.get_or_try_init_blocking(|| Ok(1));
430 /// # _explicit(&result);
431 /// assert_eq!(result.unwrap(), &1);
432 ///
433 /// let result = cell.get_or_try_init_blocking(|| Err(()));
434 ///
435 /// assert_eq!(result.unwrap(), &1);
436 /// ```
437 #[cfg(all(feature = "std", not(target_family = "wasm")))]
438 pub fn get_or_try_init_blocking<E>(
439 &self,
440 closure: impl FnOnce() -> Result<T, E>,
441 ) -> Result<&T, E> {
442 // Fast path: see if the value is already initialized.
443 if let Some(value) = self.get() {
444 return Ok(value);
445 }
446
447 // Slow path: initialize the value.
448 // The futures provided should never block, so we can use `now_or_never`.
449 now_or_never(self.initialize_or_wait(
450 move || core::future::ready(closure()),
451 &mut event_listener_strategy::Blocking::default(),
452 ))?;
453 debug_assert!(self.is_initialized());
454
455 // SAFETY: We know that the value is initialized, so it is safe to
456 // read it.
457 Ok(unsafe { self.get_unchecked() })
458 }
459
460 /// Either get the value or initialize it with the given closure.
461 ///
462 /// Many tasks may call this function, but the value will only be set once
463 /// and only one closure will be invoked.
464 ///
465 /// # Example
466 ///
467 /// ```rust
468 /// use async_lock::OnceCell;
469 ///
470 /// # futures_lite::future::block_on(async {
471 /// let cell = OnceCell::new();
472 /// assert_eq!(cell.get_or_init(|| async { 1 }).await, &1);
473 /// assert_eq!(cell.get_or_init(|| async { 2 }).await, &1);
474 /// # });
475 /// ```
476 pub async fn get_or_init<Fut: Future<Output = T>>(&self, closure: impl FnOnce() -> Fut) -> &T {
477 // false positive: https://github.com/rust-lang/rust/issues/129352
478 #[allow(unreachable_patterns)]
479 match self
480 .get_or_try_init(move || async move {
481 let result: Result<T, Infallible> = Ok(closure().await);
482 result
483 })
484 .await
485 {
486 Ok(value) => value,
487 Err(infallible) => match infallible {},
488 }
489 }
490
491 /// Either get the value or initialize it with the given closure.
492 ///
493 /// Many tasks may call this function, but the value will only be set once
494 /// and only one closure will be invoked.
495 ///
496 /// # Blocking
497 ///
498 /// In contrast to the `get_or_init` method, this method blocks the current thread of
499 /// execution instead of awaiting.
500 ///
501 /// This method should not be used in an asynchronous context. It is intended
502 /// to be used such that a `OnceCell` can be used in both asynchronous and synchronous contexts.
503 /// Calling this method in an asynchronous context may result in deadlocks.
504 ///
505 /// # Example
506 ///
507 /// ```rust
508 /// use async_lock::OnceCell;
509 ///
510 /// let cell = OnceCell::new();
511 /// assert_eq!(cell.get_or_init_blocking(|| 1), &1);
512 /// assert_eq!(cell.get_or_init_blocking(|| 2), &1);
513 /// ```
514 #[cfg(all(feature = "std", not(target_family = "wasm")))]
515 pub fn get_or_init_blocking(&self, closure: impl FnOnce() -> T + Unpin) -> &T {
516 let result = self.get_or_try_init_blocking(move || {
517 let result: Result<T, Infallible> = Ok(closure());
518 result
519 });
520
521 // false positive: https://github.com/rust-lang/rust/issues/129352
522 #[allow(unreachable_patterns)]
523 match result {
524 Ok(value) => value,
525 Err(infallible) => match infallible {},
526 }
527 }
528
529 /// Try to set the value of the cell.
530 ///
531 /// If the cell is already initialized, this method returns the original
532 /// value back.
533 ///
534 /// # Example
535 ///
536 /// ```rust
537 /// use async_lock::OnceCell;
538 ///
539 /// # futures_lite::future::block_on(async {
540 /// let cell = OnceCell::new();
541 ///
542 /// assert_eq!(cell.set(1).await, Ok(&1));
543 /// assert_eq!(cell.get(), Some(&1));
544 /// assert_eq!(cell.set(2).await, Err(2));
545 /// # });
546 /// ```
547 pub async fn set(&self, value: T) -> Result<&T, T> {
548 let mut value = Some(value);
549 self.get_or_init(|| async { value.take().unwrap() }).await;
550
551 match value {
552 Some(value) => Err(value),
553 None => {
554 // SAFETY: value was taken, so we are initialized
555 Ok(unsafe { self.get_unchecked() })
556 }
557 }
558 }
559
560 /// Try to set the value of the cell.
561 ///
562 /// If the cell is already initialized, this method returns the original
563 /// value back.
564 ///
565 /// # Blocking
566 ///
567 /// In contrast to the `set` method, this method blocks the current thread of
568 /// execution instead of awaiting.
569 ///
570 /// This method should not be used in an asynchronous context. It is intended
571 /// to be used such that a `OnceCell` can be used in both asynchronous and synchronous contexts.
572 /// Calling this method in an asynchronous context may result in deadlocks.
573 ///
574 /// # Example
575 ///
576 /// ```rust
577 /// use async_lock::OnceCell;
578 ///
579 /// let cell = OnceCell::new();
580 ///
581 /// assert_eq!(cell.set_blocking(1), Ok(&1));
582 /// assert_eq!(cell.get(), Some(&1));
583 /// assert_eq!(cell.set_blocking(2), Err(2));
584 /// ```
585 #[cfg(all(feature = "std", not(target_family = "wasm")))]
586 pub fn set_blocking(&self, value: T) -> Result<&T, T> {
587 let mut value = Some(value);
588 self.get_or_init_blocking(|| value.take().unwrap());
589
590 match value {
591 Some(value) => Err(value),
592 None => {
593 // SAFETY: value was taken, so we are initialized
594 Ok(unsafe { self.get_unchecked() })
595 }
596 }
597 }
598
599 /// Wait for the cell to be initialized, optionally using a closure
600 /// to initialize the cell if it is not initialized yet.
601 #[cold]
602 async fn initialize_or_wait<E, Fut: Future<Output = Result<T, E>>, F: FnOnce() -> Fut>(
603 &self,
604 closure: F,
605 strategy: &mut impl for<'a> Strategy<'a>,
606 ) -> Result<(), E> {
607 // The event listener we're currently waiting on.
608 let mut event_listener = None;
609
610 let mut closure = Some(closure);
611
612 loop {
613 // Check the current state of the cell.
614 let state = self.state.load(Ordering::Acquire);
615
616 // Determine what we should do based on our state.
617 match state.into() {
618 State::Initialized => {
619 // The cell is initialized now, so we can return.
620 return Ok(());
621 }
622 State::Initializing => {
623 // The cell is currently initializing, or the cell is uninitialized
624 // but we do not have the ability to initialize it.
625 //
626 // We need to wait the initialization to complete.
627 if let Some(listener) = event_listener.take() {
628 strategy.wait(listener).await;
629 } else {
630 event_listener = Some(self.active_initializers.listen());
631 }
632 }
633 State::Uninitialized => {
634 // Try to move the cell into the initializing state.
635 if self
636 .state
637 .compare_exchange(
638 State::Uninitialized.into(),
639 State::Initializing.into(),
640 Ordering::AcqRel,
641 Ordering::Acquire,
642 )
643 .is_err()
644 {
645 // The cell was initialized while we were trying to
646 // initialize it.
647 continue;
648 }
649
650 // Now that we have an exclusive lock on the cell's value,
651 // we can try to initialize it.
652 let _guard = Guard(self);
653 let initializer = closure.take().unwrap();
654 match (initializer)().await {
655 Ok(value) => {
656 // Write the value into the cell and update the state.
657 unsafe {
658 ptr::write(self.value.get().cast(), value);
659 }
660 forget(_guard);
661 self.state
662 .store(State::Initialized.into(), Ordering::Release);
663
664 // Notify the listeners that the value is initialized.
665 self.active_initializers.notify_additional(usize::MAX);
666 self.passive_waiters.notify_additional(usize::MAX);
667
668 return Ok(());
669 }
670 Err(err) => {
671 // Update the state to indicate that the value is
672 // uninitialized.
673 drop(_guard);
674
675 return Err(err);
676 }
677 }
678 }
679 }
680 }
681
682 /// Set the cell's state back to `UNINITIALIZED on drop.
683 ///
684 /// If the closure panics, this ensures that the cell's state is set back to
685 /// `UNINITIALIZED` and that the next listener is notified.
686 struct Guard<'a, T>(&'a OnceCell<T>);
687
688 impl<T> Drop for Guard<'_, T> {
689 fn drop(&mut self) {
690 self.0
691 .state
692 .store(State::Uninitialized.into(), Ordering::Release);
693
694 // Notify the next initializer that it's their turn.
695 self.0.active_initializers.notify(1);
696 }
697 }
698 }
699
700 /// Get a reference to the inner value.
701 ///
702 /// # Safety
703 ///
704 /// The caller must ensure that the cell is initialized.
705 ///
706 /// # Example
707 ///
708 /// ```rust
709 /// use async_lock::OnceCell;
710 ///
711 /// # futures_lite::future::block_on(async {
712 /// let cell = OnceCell::new();
713 /// cell.set(1).await;
714 ///
715 /// // SAFETY: We know that the value is initialized, so it is safe to
716 /// // read it.
717 /// assert_eq!(unsafe { cell.get_unchecked() }, &1);
718 /// # });
719 /// ```
720 pub unsafe fn get_unchecked(&self) -> &T {
721 // SAFETY: The caller asserts that the value is initialized
722 &*self.value.get().cast()
723 }
724}
725
726impl<T> From<T> for OnceCell<T> {
727 /// Create a new, initialized `OnceCell` from an existing value.
728 ///
729 /// # Example
730 ///
731 /// ```rust
732 /// use async_lock::OnceCell;
733 ///
734 /// let cell = OnceCell::from(42);
735 /// assert_eq!(cell.get(), Some(&42));
736 /// ```
737 fn from(value: T) -> Self {
738 Self {
739 active_initializers: Event::new(),
740 passive_waiters: Event::new(),
741 state: AtomicUsize::new(State::Initialized.into()),
742 value: UnsafeCell::new(MaybeUninit::new(value)),
743 }
744 }
745}
746
747impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
748 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
749 struct Inner<'a, T>(&'a OnceCell<T>);
750
751 impl<T: fmt::Debug> fmt::Debug for Inner<'_, T> {
752 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753 match self.0.state.load(Ordering::Acquire).into() {
754 State::Uninitialized => f.write_str("<uninitialized>"),
755 State::Initializing => f.write_str("<initializing>"),
756 State::Initialized => {
757 // SAFETY: "value" is initialized.
758 let value = unsafe { self.0.get_unchecked() };
759 fmt::Debug::fmt(value, f)
760 }
761 }
762 }
763 }
764
765 f.debug_tuple("OnceCell").field(&Inner(self)).finish()
766 }
767}
768
769impl<T> Drop for OnceCell<T> {
770 fn drop(&mut self) {
771 self.state.with_mut(|state| {
772 if State::from(*state) == State::Initialized {
773 // SAFETY: We know that the value is initialized, so it is safe to
774 // drop it.
775 unsafe { self.value.get().cast::<T>().drop_in_place() }
776 }
777 });
778 }
779}
780
781impl<T> Default for OnceCell<T> {
782 // Calls `OnceCell::new`.
783 #[inline]
784 fn default() -> Self {
785 Self::new()
786 }
787}
788
789/// Either return the result of a future now, or panic.
790#[cfg(all(feature = "std", not(target_family = "wasm")))]
791fn now_or_never<T>(f: impl Future<Output = T>) -> T {
792 use core::pin::pin;
793 use core::task::{Context, Poll, Waker};
794
795 // Poll the future exactly once.
796 let f = pin!(f);
797 let mut cx = Context::from_waker(Waker::noop());
798
799 match f.poll(&mut cx) {
800 Poll::Ready(value) => value,
801 Poll::Pending => unreachable!("future not ready"),
802 }
803}