diff --git a/tracing-core/src/spin/once.rs b/tracing-core/src/spin/once.rs index 27c99e56ee..5233b39035 100644 --- a/tracing-core/src/spin/once.rs +++ b/tracing-core/src/spin/once.rs @@ -2,6 +2,7 @@ use core::cell::UnsafeCell; use core::fmt; use core::hint::spin_loop; use core::sync::atomic::{AtomicUsize, Ordering}; +use core::mem::MaybeUninit; /// A synchronization primitive which can be used to run a one-time global /// initialization. Unlike its std equivalent, this is generalized so that the @@ -9,7 +10,7 @@ use core::sync::atomic::{AtomicUsize, Ordering}; /// a future, too. pub struct Once { state: AtomicUsize, - data: UnsafeCell>, // TODO remove option and use mem::uninitialized + data: UnsafeCell>, } impl fmt::Debug for Once { @@ -41,7 +42,7 @@ impl Once { /// Initialization constant of `Once`. pub const INIT: Self = Once { state: AtomicUsize::new(INCOMPLETE), - data: UnsafeCell::new(None), + data: UnsafeCell::new(MaybeUninit::uninit()), }; /// Creates a new `Once` value. @@ -50,10 +51,7 @@ impl Once { } fn force_get<'a>(&'a self) -> &'a T { - match unsafe { &*self.data.get() }.as_ref() { - None => unsafe { unreachable() }, - Some(p) => p, - } + unsafe { (*self.data.get()).assume_init_ref() } } /// Performs an initialization routine once and only once. The given closure @@ -91,7 +89,9 @@ impl Once { state: &self.state, panicked: true, }; - unsafe { *self.data.get() = Some(builder()) }; + unsafe { + *self.data.get() = MaybeUninit::new(builder()); + }; finish.panicked = false; self.state.store(COMPLETE, Ordering::SeqCst);