@@ -284,13 +284,15 @@ mod lazy {
284284 }
285285
286286 pub unsafe fn get ( & self ) -> Option < & ' static T > {
287- // SAFETY: No reference is ever handed out to the inner cell nor
288- // mutable reference to the Option<T> inside said cell. This make it
289- // safe to hand a reference, though the lifetime of 'static
290- // is itself unsafe, making the get method unsafe.
287+ // SAFETY: The caller must ensure no reference is ever handed out to
288+ // the inner cell nor mutable reference to the Option<T> inside said
289+ // cell. This make it safe to hand a reference, though the lifetime
290+ // of 'static is itself unsafe, making the get method unsafe.
291291 unsafe { ( * self . inner . get ( ) ) . as_ref ( ) }
292292 }
293293
294+ /// The caller must ensure that no reference is active: this method
295+ /// needs unique access.
294296 pub unsafe fn initialize < F : FnOnce ( ) -> T > ( & self , init : F ) -> & ' static T {
295297 // Execute the initialization up front, *then* move it into our slot,
296298 // just in case initialization fails.
@@ -312,20 +314,13 @@ mod lazy {
312314 // destructor" flag we just use `mem::replace` which should sequence the
313315 // operations a little differently and make this safe to call.
314316 //
315- // `ptr` can be dereferenced safely since it was obtained from
316- // `UnsafeCell::get`, which should not return a non-aligned or NUL pointer.
317- // What's more a `LazyKeyInner` can only be created with `new`, which ensures
318- // `inner` is correctly initialized and all calls to methods on `LazyKeyInner`
319- // will leave `inner` initialized too.
317+ // The precondition also ensures that we are the only one accessing
318+ // `self` at the moment so replacing is fine.
320319 unsafe {
321320 let _ = mem:: replace ( & mut * ptr, Some ( value) ) ;
322321 }
323322
324- // SAFETY: the `*ptr` operation is made safe by the `mem::replace`
325- // call above combined with `ptr` being correct from the beginning
326- // (see previous SAFETY: comment above).
327- //
328- // Plus, with the call to `mem::replace` it is guaranteed there is
323+ // SAFETY: With the call to `mem::replace` it is guaranteed there is
329324 // a `Some` behind `ptr`, not a `None` so `unreachable_unchecked`
330325 // will never be reached.
331326 unsafe {
@@ -341,11 +336,12 @@ mod lazy {
341336 }
342337 }
343338
339+ /// The other methods hand out references while taking &self.
340+ /// As such, callers of this method must ensure no `&` and `&mut` are
341+ /// available and used at the same time.
344342 #[ allow( unused) ]
345343 pub unsafe fn take ( & mut self ) -> Option < T > {
346- // SAFETY: The other methods hand out references while taking &self.
347- // As such, callers of this method must ensure no `&` and `&mut` are
348- // available and used at the same time.
344+ // SAFETY: See doc comment for this method.
349345 unsafe { ( * self . inner . get ( ) ) . take ( ) }
350346 }
351347 }
@@ -438,9 +434,10 @@ pub mod fast {
438434 // SAFETY: See the definitions of `LazyKeyInner::get` and
439435 // `try_initialize` for more informations.
440436 //
441- // The call to `get` is made safe because no mutable references are
442- // ever handed out and the `try_initialize` is dependant on the
443- // passed `init` function.
437+ // The caller must ensure no mutable references are ever active to
438+ // the inner cell or the inner T when this is called.
439+ // The `try_initialize` is dependant on the passed `init` function
440+ // for this.
444441 unsafe {
445442 match self . inner . get ( ) {
446443 Some ( val) => Some ( val) ,
@@ -546,9 +543,10 @@ pub mod os {
546543 Key { os : OsStaticKey :: new ( Some ( destroy_value :: < T > ) ) , marker : marker:: PhantomData }
547544 }
548545
546+ /// It is a requirement for the caller to ensure that no mutable
547+ /// reference is active when this method is called.
549548 pub unsafe fn get ( & ' static self , init : fn ( ) -> T ) -> Option < & ' static T > {
550- // SAFETY: No mutable references are ever handed out meaning getting
551- // the value is ok.
549+ // SAFETY: See the documentation for this method.
552550 let ptr = unsafe { self . os . get ( ) as * mut Value < T > } ;
553551 if ptr as usize > 1 {
554552 // SAFETY: the check ensured the pointer is safe (its destructor
0 commit comments