@@ -284,13 +284,15 @@ mod lazy {
284
284
}
285
285
286
286
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.
291
291
unsafe { ( * self . inner . get ( ) ) . as_ref ( ) }
292
292
}
293
293
294
+ /// The caller must ensure that no reference is active: this method
295
+ /// needs unique access.
294
296
pub unsafe fn initialize < F : FnOnce ( ) -> T > ( & self , init : F ) -> & ' static T {
295
297
// Execute the initialization up front, *then* move it into our slot,
296
298
// just in case initialization fails.
@@ -312,20 +314,13 @@ mod lazy {
312
314
// destructor" flag we just use `mem::replace` which should sequence the
313
315
// operations a little differently and make this safe to call.
314
316
//
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.
320
319
unsafe {
321
320
let _ = mem:: replace ( & mut * ptr, Some ( value) ) ;
322
321
}
323
322
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
329
324
// a `Some` behind `ptr`, not a `None` so `unreachable_unchecked`
330
325
// will never be reached.
331
326
unsafe {
@@ -341,11 +336,12 @@ mod lazy {
341
336
}
342
337
}
343
338
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.
344
342
#[ allow( unused) ]
345
343
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.
349
345
unsafe { ( * self . inner . get ( ) ) . take ( ) }
350
346
}
351
347
}
@@ -438,9 +434,10 @@ pub mod fast {
438
434
// SAFETY: See the definitions of `LazyKeyInner::get` and
439
435
// `try_initialize` for more informations.
440
436
//
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.
444
441
unsafe {
445
442
match self . inner . get ( ) {
446
443
Some ( val) => Some ( val) ,
@@ -546,9 +543,10 @@ pub mod os {
546
543
Key { os : OsStaticKey :: new ( Some ( destroy_value :: < T > ) ) , marker : marker:: PhantomData }
547
544
}
548
545
546
+ /// It is a requirement for the caller to ensure that no mutable
547
+ /// reference is active when this method is called.
549
548
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.
552
550
let ptr = unsafe { self . os . get ( ) as * mut Value < T > } ;
553
551
if ptr as usize > 1 {
554
552
// SAFETY: the check ensured the pointer is safe (its destructor
0 commit comments