Skip to content

Commit 0eef67b

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

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

library/std/src/sync/once_lock.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ impl<T> OnceLock<T> {
152152
#[stable(feature = "once_cell", since = "1.70.0")]
153153
#[rustc_should_not_be_called_on_const_items]
154154
pub fn get(&self) -> Option<&T> {
155-
if self.is_initialized() {
156-
// Safe b/c checked is_initialized
155+
if self.initialized() {
156+
// Safe b/c checked initialized
157157
Some(unsafe { self.get_unchecked() })
158158
} else {
159159
None
@@ -170,8 +170,8 @@ impl<T> OnceLock<T> {
170170
#[inline]
171171
#[stable(feature = "once_cell", since = "1.70.0")]
172172
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
173+
if self.initialized_mut() {
174+
// Safe b/c checked initialized and we have a unique access
175175
Some(unsafe { self.get_unchecked_mut() })
176176
} else {
177177
None
@@ -402,14 +402,12 @@ impl<T> OnceLock<T> {
402402
// NOTE: We need to perform an acquire on the state in this method
403403
// in order to correctly synchronize `LazyLock::force`. This is
404404
// currently done by calling `self.get()`, which in turn calls
405-
// `self.is_initialized()`, which in turn performs the acquire.
405+
// `self.initialized()`, which in turn performs the acquire.
406406
if let Some(value) = self.get() {
407407
return Ok(value);
408408
}
409409
self.initialize(f)?;
410410

411-
debug_assert!(self.is_initialized());
412-
413411
// SAFETY: The inner value has been initialized
414412
Ok(unsafe { self.get_unchecked() })
415413
}
@@ -451,10 +449,10 @@ impl<T> OnceLock<T> {
451449
where
452450
F: FnOnce() -> Result<T, E>,
453451
{
454-
if self.get().is_none() {
452+
if self.get_mut().is_none() {
455453
self.initialize(f)?;
456454
}
457-
debug_assert!(self.is_initialized());
455+
458456
// SAFETY: The inner value has been initialized
459457
Ok(unsafe { self.get_unchecked_mut() })
460458
}
@@ -503,22 +501,32 @@ impl<T> OnceLock<T> {
503501
#[inline]
504502
#[stable(feature = "once_cell", since = "1.70.0")]
505503
pub fn take(&mut self) -> Option<T> {
506-
if self.is_initialized() {
504+
if self.initialized_mut() {
507505
self.once = Once::new();
508506
// SAFETY: `self.value` is initialized and contains a valid `T`.
509-
// `self.once` is reset, so `is_initialized()` will be false again
507+
// `self.once` is reset, so `initialized()` will be false again
510508
// which prevents the value from being read twice.
511-
unsafe { Some((&mut *self.value.get()).assume_init_read()) }
509+
unsafe { Some(self.value.get_mut().assume_init_read()) }
512510
} else {
513511
None
514512
}
515513
}
516514

517515
#[inline]
518-
fn is_initialized(&self) -> bool {
516+
fn initialized(&self) -> bool {
519517
self.once.is_completed()
520518
}
521519

520+
#[inline]
521+
fn initialized_mut(&mut self) -> bool {
522+
// `state()` does not perform an atomic load, so prefer it over `is_complete()`.
523+
let state = self.once.state();
524+
match state {
525+
crate::sync::once::OnceState::Completed => true,
526+
_ => false,
527+
}
528+
}
529+
522530
#[cold]
523531
#[optimize(size)]
524532
fn initialize<F, E>(&self, f: F) -> Result<(), E>
@@ -552,7 +560,7 @@ impl<T> OnceLock<T> {
552560
/// The cell must be initialized
553561
#[inline]
554562
unsafe fn get_unchecked(&self) -> &T {
555-
debug_assert!(self.is_initialized());
563+
debug_assert!(self.initialized());
556564
unsafe { (&*self.value.get()).assume_init_ref() }
557565
}
558566

@@ -561,8 +569,8 @@ impl<T> OnceLock<T> {
561569
/// The cell must be initialized
562570
#[inline]
563571
unsafe fn get_unchecked_mut(&mut self) -> &mut T {
564-
debug_assert!(self.is_initialized());
565-
unsafe { (&mut *self.value.get()).assume_init_mut() }
572+
debug_assert!(self.initialized_mut());
573+
unsafe { self.value.get_mut().assume_init_mut() }
566574
}
567575
}
568576

@@ -689,11 +697,11 @@ impl<T: Eq> Eq for OnceLock<T> {}
689697
unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
690698
#[inline]
691699
fn drop(&mut self) {
692-
if self.is_initialized() {
700+
if self.initialized_mut() {
693701
// SAFETY: The cell is initialized and being dropped, so it can't
694702
// be accessed again. We also don't touch the `T` other than
695703
// dropping it, which validates our usage of #[may_dangle].
696-
unsafe { (&mut *self.value.get()).assume_init_drop() };
704+
unsafe { self.value.get_mut().assume_init_drop() };
697705
}
698706
}
699707
}

0 commit comments

Comments
 (0)