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