Skip to main content

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, without blocking.
561    ///
562    /// If the cell is already initialised *or* the is currently in the process of being
563    /// initialised, this method returns the original value back.
564    ///
565    /// Unlike [`OnceCell::set`] and [`OnceCell::set_blocking`], this function is neither
566    /// blocking nor async.
567    pub fn try_set(&self, value: T) -> Result<(), T> {
568        if self
569            .state
570            .compare_exchange(
571                State::Uninitialized.into(),
572                State::Initializing.into(),
573                Ordering::AcqRel,
574                Ordering::Acquire,
575            )
576            .is_ok()
577        {
578            // Write the value into the cell and update the state.
579            unsafe {
580                ptr::write(self.value.get().cast(), value);
581            }
582            // Mark the OnceCell as initialised
583            self.state
584                .store(State::Initialized.into(), Ordering::Release);
585
586            // Notify the listeners that the value is initialized.
587            self.active_initializers.notify_additional(usize::MAX);
588            self.passive_waiters.notify_additional(usize::MAX);
589            Ok(())
590        } else {
591            // The cell was either initialised or is in the process of being initialised,
592            // so the given value is not needed.
593            Err(value)
594        }
595    }
596
597    /// Try to set the value of the cell.
598    ///
599    /// If the cell is already initialized, this method returns the original
600    /// value back.
601    ///
602    /// # Blocking
603    ///
604    /// In contrast to the `set` method, this method blocks the current thread of
605    /// execution instead of awaiting.
606    ///
607    /// This method should not be used in an asynchronous context. It is intended
608    /// to be used such that a `OnceCell` can be used in both asynchronous and synchronous contexts.
609    /// Calling this method in an asynchronous context may result in deadlocks.
610    ///
611    /// # Example
612    ///
613    /// ```rust
614    /// use async_lock::OnceCell;
615    ///
616    /// let cell = OnceCell::new();
617    ///
618    /// assert_eq!(cell.set_blocking(1), Ok(&1));
619    /// assert_eq!(cell.get(), Some(&1));
620    /// assert_eq!(cell.set_blocking(2), Err(2));
621    /// ```
622    #[cfg(all(feature = "std", not(target_family = "wasm")))]
623    pub fn set_blocking(&self, value: T) -> Result<&T, T> {
624        let mut value = Some(value);
625        self.get_or_init_blocking(|| value.take().unwrap());
626
627        match value {
628            Some(value) => Err(value),
629            None => {
630                // SAFETY: value was taken, so we are initialized
631                Ok(unsafe { self.get_unchecked() })
632            }
633        }
634    }
635
636    /// Wait for the cell to be initialized, optionally using a closure
637    /// to initialize the cell if it is not initialized yet.
638    #[cold]
639    async fn initialize_or_wait<E, Fut: Future<Output = Result<T, E>>, F: FnOnce() -> Fut>(
640        &self,
641        closure: F,
642        strategy: &mut impl for<'a> Strategy<'a>,
643    ) -> Result<(), E> {
644        // The event listener we're currently waiting on.
645        let mut event_listener = None;
646
647        let mut closure = Some(closure);
648
649        loop {
650            // Check the current state of the cell.
651            let state = self.state.load(Ordering::Acquire);
652
653            // Determine what we should do based on our state.
654            match state.into() {
655                State::Initialized => {
656                    // The cell is initialized now, so we can return.
657                    return Ok(());
658                }
659                State::Initializing => {
660                    // The cell is currently initializing, or the cell is uninitialized
661                    // but we do not have the ability to initialize it.
662                    //
663                    // We need to wait the initialization to complete.
664                    if let Some(listener) = event_listener.take() {
665                        strategy.wait(listener).await;
666                    } else {
667                        event_listener = Some(self.active_initializers.listen());
668                    }
669                }
670                State::Uninitialized => {
671                    // Try to move the cell into the initializing state.
672                    if self
673                        .state
674                        .compare_exchange(
675                            State::Uninitialized.into(),
676                            State::Initializing.into(),
677                            Ordering::AcqRel,
678                            Ordering::Acquire,
679                        )
680                        .is_err()
681                    {
682                        // The cell was initialized while we were trying to
683                        // initialize it.
684                        continue;
685                    }
686
687                    // Now that we have an exclusive lock on the cell's value,
688                    // we can try to initialize it.
689                    let _guard = Guard(self);
690                    let initializer = closure.take().unwrap();
691                    match (initializer)().await {
692                        Ok(value) => {
693                            // Write the value into the cell and update the state.
694                            unsafe {
695                                ptr::write(self.value.get().cast(), value);
696                            }
697                            forget(_guard);
698                            self.state
699                                .store(State::Initialized.into(), Ordering::Release);
700
701                            // Notify the listeners that the value is initialized.
702                            self.active_initializers.notify_additional(usize::MAX);
703                            self.passive_waiters.notify_additional(usize::MAX);
704
705                            return Ok(());
706                        }
707                        Err(err) => {
708                            // Update the state to indicate that the value is
709                            // uninitialized.
710                            drop(_guard);
711
712                            return Err(err);
713                        }
714                    }
715                }
716            }
717        }
718
719        /// Set the cell's state back to `UNINITIALIZED on drop.
720        ///
721        /// If the closure panics, this ensures that the cell's state is set back to
722        /// `UNINITIALIZED` and that the next listener is notified.
723        struct Guard<'a, T>(&'a OnceCell<T>);
724
725        impl<T> Drop for Guard<'_, T> {
726            fn drop(&mut self) {
727                self.0
728                    .state
729                    .store(State::Uninitialized.into(), Ordering::Release);
730
731                // Notify the next initializer that it's their turn.
732                self.0.active_initializers.notify(1);
733            }
734        }
735    }
736
737    /// Get a reference to the inner value.
738    ///
739    /// # Safety
740    ///
741    /// The caller must ensure that the cell is initialized.
742    ///
743    /// # Example
744    ///
745    /// ```rust
746    /// use async_lock::OnceCell;
747    ///
748    /// # futures_lite::future::block_on(async {
749    /// let cell = OnceCell::new();
750    /// cell.set(1).await;
751    ///
752    /// // SAFETY: We know that the value is initialized, so it is safe to
753    /// // read it.
754    /// assert_eq!(unsafe { cell.get_unchecked() }, &1);
755    /// # });
756    /// ```
757    pub unsafe fn get_unchecked(&self) -> &T {
758        // SAFETY: The caller asserts that the value is initialized
759        &*self.value.get().cast()
760    }
761}
762
763impl<T> From<T> for OnceCell<T> {
764    /// Create a new, initialized `OnceCell` from an existing value.
765    ///
766    /// # Example
767    ///
768    /// ```rust
769    /// use async_lock::OnceCell;
770    ///
771    /// let cell = OnceCell::from(42);
772    /// assert_eq!(cell.get(), Some(&42));
773    /// ```
774    fn from(value: T) -> Self {
775        Self {
776            active_initializers: Event::new(),
777            passive_waiters: Event::new(),
778            state: AtomicUsize::new(State::Initialized.into()),
779            value: UnsafeCell::new(MaybeUninit::new(value)),
780        }
781    }
782}
783
784impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
785    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
786        struct Inner<'a, T>(&'a OnceCell<T>);
787
788        impl<T: fmt::Debug> fmt::Debug for Inner<'_, T> {
789            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
790                match self.0.state.load(Ordering::Acquire).into() {
791                    State::Uninitialized => f.write_str("<uninitialized>"),
792                    State::Initializing => f.write_str("<initializing>"),
793                    State::Initialized => {
794                        // SAFETY: "value" is initialized.
795                        let value = unsafe { self.0.get_unchecked() };
796                        fmt::Debug::fmt(value, f)
797                    }
798                }
799            }
800        }
801
802        f.debug_tuple("OnceCell").field(&Inner(self)).finish()
803    }
804}
805
806impl<T> Drop for OnceCell<T> {
807    fn drop(&mut self) {
808        self.state.with_mut(|state| {
809            if State::from(*state) == State::Initialized {
810                // SAFETY: We know that the value is initialized, so it is safe to
811                // drop it.
812                unsafe { self.value.get().cast::<T>().drop_in_place() }
813            }
814        });
815    }
816}
817
818impl<T> Default for OnceCell<T> {
819    // Calls `OnceCell::new`.
820    #[inline]
821    fn default() -> Self {
822        Self::new()
823    }
824}
825
826/// Either return the result of a future now, or panic.
827#[cfg(all(feature = "std", not(target_family = "wasm")))]
828fn now_or_never<T>(f: impl Future<Output = T>) -> T {
829    use core::pin::pin;
830    use core::task::{Context, Poll, Waker};
831
832    // Poll the future exactly once.
833    let f = pin!(f);
834    let mut cx = Context::from_waker(Waker::noop());
835
836    match f.poll(&mut cx) {
837        Poll::Ready(value) => value,
838        Poll::Pending => unreachable!("future not ready"),
839    }
840}