@@ -288,13 +288,15 @@ mod lazy {
288288 }
289289
290290 pub unsafe fn get ( & self ) -> Option < & ' static T > {
291- // SAFETY: No reference is ever handed out to the inner cell nor
292- // mutable reference to the Option<T> inside said cell. This make it
293- // safe to hand a reference, though the lifetime of 'static
294- // is itself unsafe, making the get method unsafe.
291+ // SAFETY: The caller must ensure no reference is ever handed out to
292+ // the inner cell nor mutable reference to the Option<T> inside said
293+ // cell. This make it safe to hand a reference, though the lifetime
294+ // of 'static is itself unsafe, making the get method unsafe.
295295 unsafe { ( * self . inner . get ( ) ) . as_ref ( ) }
296296 }
297297
298+ /// The caller must ensure that no reference is active: this method
299+ /// needs unique access.
298300 pub unsafe fn initialize < F : FnOnce ( ) -> T > ( & self , init : F ) -> & ' static T {
299301 // Execute the initialization up front, *then* move it into our slot,
300302 // just in case initialization fails.
@@ -316,20 +318,13 @@ mod lazy {
316318 // destructor" flag we just use `mem::replace` which should sequence the
317319 // operations a little differently and make this safe to call.
318320 //
319- // `ptr` can be dereferenced safely since it was obtained from
320- // `UnsafeCell::get`, which should not return a non-aligned or NUL pointer.
321- // What's more a `LazyKeyInner` can only be created with `new`, which ensures
322- // `inner` is correctly initialized and all calls to methods on `LazyKeyInner`
323- // will leave `inner` initialized too.
321+ // The precondition also ensures that we are the only one accessing
322+ // `self` at the moment so replacing is fine.
324323 unsafe {
325324 let _ = mem:: replace ( & mut * ptr, Some ( value) ) ;
326325 }
327326
328- // SAFETY: the `*ptr` operation is made safe by the `mem::replace`
329- // call above combined with `ptr` being correct from the beginning
330- // (see previous SAFETY: comment above).
331- //
332- // Plus, with the call to `mem::replace` it is guaranteed there is
327+ // SAFETY: With the call to `mem::replace` it is guaranteed there is
333328 // a `Some` behind `ptr`, not a `None` so `unreachable_unchecked`
334329 // will never be reached.
335330 unsafe {
@@ -345,11 +340,12 @@ mod lazy {
345340 }
346341 }
347342
343+ /// The other methods hand out references while taking &self.
344+ /// As such, callers of this method must ensure no `&` and `&mut` are
345+ /// available and used at the same time.
348346 #[ allow( unused) ]
349347 pub unsafe fn take ( & mut self ) -> Option < T > {
350- // SAFETY: The other methods hand out references while taking &self.
351- // As such, callers of this method must ensure no `&` and `&mut` are
352- // available and used at the same time.
348+ // SAFETY: See doc comment for this method.
353349 unsafe { ( * self . inner . get ( ) ) . take ( ) }
354350 }
355351 }
@@ -442,9 +438,10 @@ pub mod fast {
442438 // SAFETY: See the definitions of `LazyKeyInner::get` and
443439 // `try_initialize` for more informations.
444440 //
445- // The call to `get` is made safe because no mutable references are
446- // ever handed out and the `try_initialize` is dependant on the
447- // passed `init` function.
441+ // The caller must ensure no mutable references are ever active to
442+ // the inner cell or the inner T when this is called.
443+ // The `try_initialize` is dependant on the passed `init` function
444+ // for this.
448445 unsafe {
449446 match self . inner . get ( ) {
450447 Some ( val) => Some ( val) ,
@@ -549,9 +546,10 @@ pub mod os {
549546 Key { os : OsStaticKey :: new ( Some ( destroy_value :: < T > ) ) , marker : marker:: PhantomData }
550547 }
551548
549+ /// It is a requirement for the caller to ensure that no mutable
550+ /// reference is active when this method is called.
552551 pub unsafe fn get ( & ' static self , init : fn ( ) -> T ) -> Option < & ' static T > {
553- // SAFETY: No mutable references are ever handed out meaning getting
554- // the value is ok.
552+ // SAFETY: See the documentation for this method.
555553 let ptr = unsafe { self . os . get ( ) as * mut Value < T > } ;
556554 if ptr as usize > 1 {
557555 // SAFETY: the check ensured the pointer is safe (its destructor
0 commit comments