11use super :: once:: OnceExclusiveState ;
2- use crate :: cell:: UnsafeCell ;
2+ use crate :: cell:: CovariantUnsafeCell ;
33use crate :: mem:: ManuallyDrop ;
44use crate :: ops:: { Deref , DerefMut } ;
55use crate :: panic:: { RefUnwindSafe , UnwindSafe } ;
@@ -81,7 +81,9 @@ union Data<T, F> {
8181pub struct LazyLock < T , F = fn ( ) -> T > {
8282 // FIXME(nonpoison_once): if possible, switch to nonpoison version once it is available
8383 once : Once ,
84- data : UnsafeCell < Data < T , F > > ,
84+ // See justification on `core::cell::LazyCell::state` for why this can be covariant in both
85+ // `T` and `F`.
86+ data : CovariantUnsafeCell < Data < T , F > > ,
8587}
8688
8789impl < T , F : FnOnce ( ) -> T > LazyLock < T , F > {
@@ -102,7 +104,10 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
102104 #[ stable( feature = "lazy_cell" , since = "1.80.0" ) ]
103105 #[ rustc_const_stable( feature = "lazy_cell" , since = "1.80.0" ) ]
104106 pub const fn new ( f : F ) -> LazyLock < T , F > {
105- LazyLock { once : Once :: new ( ) , data : UnsafeCell :: new ( Data { f : ManuallyDrop :: new ( f) } ) }
107+ LazyLock {
108+ once : Once :: new ( ) ,
109+ data : CovariantUnsafeCell :: new ( Data { f : ManuallyDrop :: new ( f) } ) ,
110+ }
106111 }
107112
108113 /// Consumes this `LazyLock` returning the stored value.
@@ -245,7 +250,7 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
245250 }
246251
247252 // SAFETY: `call_once` only runs this closure once, ever.
248- let data = unsafe { & mut * this. data . get ( ) } ;
253+ let data = unsafe { this. data . get ( ) . as_mut ( ) } ;
249254 let f = unsafe { ManuallyDrop :: take ( & mut data. f ) } ;
250255 let value = f ( ) ;
251256 data. value = ManuallyDrop :: new ( value) ;
@@ -258,7 +263,7 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
258263 // * the closure was not called, but a previous call initialized `value`.
259264 // * the closure was not called because the Once is poisoned, which we handled above.
260265 // So `value` has definitely been initialized and will not be modified again.
261- unsafe { & * ( * this. data . get ( ) ) . value }
266+ unsafe { & this. data . get ( ) . as_ref ( ) . value }
262267 }
263268}
264269
@@ -313,7 +318,7 @@ impl<T, F> LazyLock<T, F> {
313318 // SAFETY:
314319 // The closure has been run successfully, so `value` has been initialized
315320 // and will not be modified again.
316- Some ( unsafe { & ( * this. data . get ( ) ) . value } )
321+ Some ( unsafe { & this. data . get ( ) . as_ref ( ) . value } )
317322 } else {
318323 None
319324 }
@@ -404,7 +409,7 @@ impl<T, F> From<T> for LazyLock<T, F> {
404409 fn from ( value : T ) -> Self {
405410 LazyLock {
406411 once : Once :: new_complete ( ) ,
407- data : UnsafeCell :: new ( Data { value : ManuallyDrop :: new ( value) } ) ,
412+ data : CovariantUnsafeCell :: new ( Data { value : ManuallyDrop :: new ( value) } ) ,
408413 }
409414 }
410415}
0 commit comments