@@ -782,7 +782,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
782782mod lazy {
783783 use crate :: cell:: UnsafeCell ;
784784 use crate :: hint;
785- use crate :: mem ;
785+ use crate :: ptr ;
786786
787787 pub struct LazyKeyInner < T > {
788788 inner : UnsafeCell < Option < T > > ,
@@ -811,7 +811,7 @@ mod lazy {
811811
812812 // SAFETY:
813813 //
814- // note that this can in theory just be `*ptr = Some(value)`, but due to
814+ // Note that this can in theory just be `*ptr = Some(value)`, but due to
815815 // the compiler will currently codegen that pattern with something like:
816816 //
817817 // ptr::drop_in_place(ptr)
@@ -821,16 +821,20 @@ mod lazy {
821821 // `ptr` (e.g., if this is being recursively initialized) to re-access
822822 // TLS, in which case there will be a `&` and `&mut` pointer to the same
823823 // value (an aliasing violation). To avoid setting the "I'm running a
824- // destructor" flag we just use `mem::replace` which should sequence the
825- // operations a little differently and make this safe to call.
824+ // destructor" flag we just use `ptr::replace` which should sequence the
825+ // operations a little differently and make this safe to call:
826+ //
827+ // let tmp = ptr::read(ptr)
828+ // ptr::write(ptr, Some(value))
829+ // drop(tmp)
826830 //
827831 // The precondition also ensures that we are the only one accessing
828832 // `self` at the moment so replacing is fine.
829833 unsafe {
830- let _ = mem :: replace ( & mut * ptr, Some ( value) ) ;
834+ let _ = ptr :: replace ( ptr, Some ( value) ) ;
831835 }
832836
833- // SAFETY: With the call to `mem ::replace` it is guaranteed there is
837+ // SAFETY: With the call to `ptr ::replace` it is guaranteed there is
834838 // a `Some` behind `ptr`, not a `None` so `unreachable_unchecked`
835839 // will never be reached.
836840 unsafe {
0 commit comments