diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 78cf8841efefb..7c90aa0bd7397 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -174,14 +174,14 @@ impl T> LazyLock { guard.0.once.set_state(ExclusiveState::Complete); core::mem::forget(guard); // SAFETY: We put the value there above. - unsafe { &mut this.data.get_mut().value } + unsafe { LazyLock::get_unchecked_mut(this) } } let state = this.once.state(); match state { ExclusiveState::Poisoned => panic_poisoned(), // SAFETY: The `Once` states we completed the initialization. - ExclusiveState::Complete => unsafe { &mut this.data.get_mut().value }, + ExclusiveState::Complete => unsafe { LazyLock::get_unchecked_mut(this) }, // SAFETY: The state is `Incomplete`. ExclusiveState::Incomplete => unsafe { really_init_mut(this) }, } @@ -222,7 +222,7 @@ impl T> LazyLock { // * the closure was not called because the Once is poisoned, so this point // is never reached. // So `value` has definitely been initialized and will not be modified again. - unsafe { &*(*this.data.get()).value } + unsafe { LazyLock::get_unchecked(this) } } } @@ -251,7 +251,7 @@ impl LazyLock { match state { // SAFETY: // The closure has been run successfully, so `value` has been initialized. - ExclusiveState::Complete => Some(unsafe { &mut this.data.get_mut().value }), + ExclusiveState::Complete => Some(unsafe { LazyLock::get_unchecked_mut(this) }), _ => None, } } @@ -278,11 +278,31 @@ impl LazyLock { // SAFETY: // The closure has been run successfully, so `value` has been initialized // and will not be modified again. - Some(unsafe { &(*this.data.get()).value }) + Some(unsafe { LazyLock::get_unchecked(this) }) } else { None } } + + /// # Safety + /// + /// The lazy must be initialized + #[inline] + #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "138914")] + pub unsafe fn get_unchecked(this: &LazyLock) -> &T { + debug_assert!(this.once.is_completed()); + unsafe { &*(*this.data.get()).value } + } + + /// # Safety + /// + /// The lazy must be initialized + #[inline] + #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "138914")] + pub unsafe fn get_unchecked_mut(this: &mut LazyLock) -> &mut T { + debug_assert!(this.once.is_completed()); + unsafe { &mut *this.data.get_mut().value } + } } #[stable(feature = "lazy_cell", since = "1.80.0")] diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index ffb90b1469584..f1f5fc0b31a52 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -535,7 +535,8 @@ impl OnceLock { /// /// The cell must be initialized #[inline] - unsafe fn get_unchecked(&self) -> &T { + #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "138914")] + pub unsafe fn get_unchecked(&self) -> &T { debug_assert!(self.is_initialized()); unsafe { (&*self.value.get()).assume_init_ref() } } @@ -544,7 +545,8 @@ impl OnceLock { /// /// The cell must be initialized #[inline] - unsafe fn get_unchecked_mut(&mut self) -> &mut T { + #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "138914")] + pub unsafe fn get_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.is_initialized()); unsafe { (&mut *self.value.get()).assume_init_mut() } }