1+ use super :: once:: OnceExclusiveState ;
12use crate :: cell:: UnsafeCell ;
23use crate :: fmt;
34use 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> {}
689698unsafe 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