Skip to content

Commit 0e33668

Browse files
committed
Leverage &mut in OnceLock when possible
Signed-off-by: tison <wander4096@gmail.com>
1 parent 3ff30e7 commit 0e33668

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

library/std/src/sync/once_lock.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::once::OnceExclusiveState;
12
use crate::cell::UnsafeCell;
23
use crate::fmt;
34
use crate::marker::PhantomData;
@@ -152,8 +153,8 @@ impl<T> OnceLock<T> {
152153
#[stable(feature = "once_cell", since = "1.70.0")]
153154
#[rustc_should_not_be_called_on_const_items]
154155
pub fn get(&self) -> Option<&T> {
155-
if self.is_initialized() {
156-
// Safe b/c checked is_initialized
156+
if self.initialized() {
157+
// Safe b/c checked initialized
157158
Some(unsafe { self.get_unchecked() })
158159
} else {
159160
None
@@ -170,8 +171,8 @@ impl<T> OnceLock<T> {
170171
#[inline]
171172
#[stable(feature = "once_cell", since = "1.70.0")]
172173
pub fn get_mut(&mut self) -> Option<&mut T> {
173-
if self.is_initialized() {
174-
// Safe b/c checked is_initialized and we have a unique access
174+
if self.initialized_mut() {
175+
// Safe b/c checked initialized and we have a unique access
175176
Some(unsafe { self.get_unchecked_mut() })
176177
} else {
177178
None
@@ -402,14 +403,12 @@ impl<T> OnceLock<T> {
402403
// NOTE: We need to perform an acquire on the state in this method
403404
// in order to correctly synchronize `LazyLock::force`. This is
404405
// currently done by calling `self.get()`, which in turn calls
405-
// `self.is_initialized()`, which in turn performs the acquire.
406+
// `self.initialized()`, which in turn performs the acquire.
406407
if let Some(value) = self.get() {
407408
return Ok(value);
408409
}
409410
self.initialize(f)?;
410411

411-
debug_assert!(self.is_initialized());
412-
413412
// SAFETY: The inner value has been initialized
414413
Ok(unsafe { self.get_unchecked() })
415414
}
@@ -451,10 +450,10 @@ impl<T> OnceLock<T> {
451450
where
452451
F: FnOnce() -> Result<T, E>,
453452
{
454-
if self.get().is_none() {
453+
if self.get_mut().is_none() {
455454
self.initialize(f)?;
456455
}
457-
debug_assert!(self.is_initialized());
456+
458457
// SAFETY: The inner value has been initialized
459458
Ok(unsafe { self.get_unchecked_mut() })
460459
}
@@ -503,22 +502,32 @@ impl<T> OnceLock<T> {
503502
#[inline]
504503
#[stable(feature = "once_cell", since = "1.70.0")]
505504
pub fn take(&mut self) -> Option<T> {
506-
if self.is_initialized() {
505+
if self.initialized_mut() {
507506
self.once = Once::new();
508507
// SAFETY: `self.value` is initialized and contains a valid `T`.
509-
// `self.once` is reset, so `is_initialized()` will be false again
508+
// `self.once` is reset, so `initialized()` will be false again
510509
// which prevents the value from being read twice.
511-
unsafe { Some((&mut *self.value.get()).assume_init_read()) }
510+
unsafe { Some(self.value.get_mut().assume_init_read()) }
512511
} else {
513512
None
514513
}
515514
}
516515

517516
#[inline]
518-
fn is_initialized(&self) -> bool {
517+
fn initialized(&self) -> bool {
519518
self.once.is_completed()
520519
}
521520

521+
#[inline]
522+
fn initialized_mut(&mut self) -> bool {
523+
// `state()` does not perform an atomic load, so prefer it over `is_complete()`.
524+
let state = self.once.state();
525+
match state {
526+
OnceExclusiveState::Complete => true,
527+
_ => false,
528+
}
529+
}
530+
522531
#[cold]
523532
#[optimize(size)]
524533
fn initialize<F, E>(&self, f: F) -> Result<(), E>
@@ -552,7 +561,7 @@ impl<T> OnceLock<T> {
552561
/// The cell must be initialized
553562
#[inline]
554563
unsafe fn get_unchecked(&self) -> &T {
555-
debug_assert!(self.is_initialized());
564+
debug_assert!(self.initialized());
556565
unsafe { (&*self.value.get()).assume_init_ref() }
557566
}
558567

@@ -561,8 +570,8 @@ impl<T> OnceLock<T> {
561570
/// The cell must be initialized
562571
#[inline]
563572
unsafe fn get_unchecked_mut(&mut self) -> &mut T {
564-
debug_assert!(self.is_initialized());
565-
unsafe { (&mut *self.value.get()).assume_init_mut() }
573+
debug_assert!(self.initialized_mut());
574+
unsafe { self.value.get_mut().assume_init_mut() }
566575
}
567576
}
568577

@@ -689,11 +698,11 @@ impl<T: Eq> Eq for OnceLock<T> {}
689698
unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
690699
#[inline]
691700
fn drop(&mut self) {
692-
if self.is_initialized() {
701+
if self.initialized_mut() {
693702
// SAFETY: The cell is initialized and being dropped, so it can't
694703
// be accessed again. We also don't touch the `T` other than
695704
// dropping it, which validates our usage of #[may_dangle].
696-
unsafe { (&mut *self.value.get()).assume_init_drop() };
705+
unsafe { self.value.get_mut().assume_init_drop() };
697706
}
698707
}
699708
}

0 commit comments

Comments
 (0)