From 6522a9ad8f8c2c65e78a9b83367942dbc5d9b554 Mon Sep 17 00:00:00 2001 From: HomelikeBrick42 <64717463+HomelikeBrick42@users.noreply.github.com> Date: Tue, 25 Mar 2025 12:26:11 +1300 Subject: [PATCH 1/2] Added `get_unchecked` and `get_unchecked_mut` to `OnceLock` and `LazyLock` --- library/std/src/sync/lazy_lock.rs | 30 +++++++++++++++++++++++++----- library/std/src/sync/once_lock.rs | 6 ++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 78cf8841efefb..77ca73ab84214 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 = "1")] + 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 = "1")] + 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..e86869c333936 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 = "1")] + 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 = "1")] + pub unsafe fn get_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.is_initialized()); unsafe { (&mut *self.value.get()).assume_init_mut() } } From 0809916da4c10210b43cf84585f1be03cff95ec4 Mon Sep 17 00:00:00 2001 From: HomelikeBrick42 <64717463+HomelikeBrick42@users.noreply.github.com> Date: Tue, 25 Mar 2025 12:55:19 +1300 Subject: [PATCH 2/2] Updated the issue number --- library/std/src/sync/lazy_lock.rs | 4 ++-- library/std/src/sync/once_lock.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 77ca73ab84214..7c90aa0bd7397 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -288,7 +288,7 @@ impl LazyLock { /// /// The lazy must be initialized #[inline] - #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "1")] + #[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 } @@ -298,7 +298,7 @@ impl LazyLock { /// /// The lazy must be initialized #[inline] - #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "1")] + #[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 } diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index e86869c333936..f1f5fc0b31a52 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -535,7 +535,7 @@ impl OnceLock { /// /// The cell must be initialized #[inline] - #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "1")] + #[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() } @@ -545,7 +545,7 @@ impl OnceLock { /// /// The cell must be initialized #[inline] - #[unstable(feature = "once_lazy_lock_get_unchecked", issue = "1")] + #[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() }