@@ -315,12 +315,23 @@ mod lazy {
315
315
// value (an aliasing violation). To avoid setting the "I'm running a
316
316
// destructor" flag we just use `mem::replace` which should sequence the
317
317
// operations a little differently and make this safe to call.
318
+ //
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.
318
324
unsafe {
319
325
let _ = mem:: replace ( & mut * ptr, Some ( value) ) ;
320
326
}
321
327
322
- // SAFETY: the *ptr operation is made safe by the `mem::replace`
323
- // call above that made sure a valid value is present behind it.
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
333
+ // a `Some` behind `ptr`, not a `None` so `unreachable_unchecked`
334
+ // will never be reached.
324
335
unsafe {
325
336
// After storing `Some` we want to get a reference to the contents of
326
337
// what we just stored. While we could use `unwrap` here and it should
@@ -337,8 +348,8 @@ mod lazy {
337
348
#[ allow( unused) ]
338
349
pub unsafe fn take ( & mut self ) -> Option < T > {
339
350
// SAFETY: The other methods hand out references while taking &self.
340
- // As such, calling this method when such references are still alive
341
- // will fail because it takes a &mut self, conflicting with them .
351
+ // As such, callers of this method must ensure no `&` and `&mut` are
352
+ // available and used at the same time .
342
353
unsafe { ( * self . inner . get ( ) ) . take ( ) }
343
354
}
344
355
}
@@ -451,9 +462,9 @@ pub mod fast {
451
462
// LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
452
463
#[ inline( never) ]
453
464
unsafe fn try_initialize < F : FnOnce ( ) -> T > ( & self , init : F ) -> Option < & ' static T > {
454
- // SAFETY: See comment above.
465
+ // SAFETY: See comment above (this function doc) .
455
466
if !mem:: needs_drop :: < T > ( ) || unsafe { self . try_register_dtor ( ) } {
456
- // SAFETY: See comment above.
467
+ // SAFETY: See comment above (his function doc) .
457
468
Some ( unsafe { self . inner . initialize ( init) } )
458
469
} else {
459
470
None
0 commit comments