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}