@@ -288,13 +288,15 @@ mod lazy {
288
288
}
289
289
290
290
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.
295
295
unsafe { ( * self . inner . get ( ) ) . as_ref ( ) }
296
296
}
297
297
298
+ /// The caller must ensure that no reference is active: this method
299
+ /// needs unique access.
298
300
pub unsafe fn initialize < F : FnOnce ( ) -> T > ( & self , init : F ) -> & ' static T {
299
301
// Execute the initialization up front, *then* move it into our slot,
300
302
// just in case initialization fails.
@@ -316,20 +318,13 @@ mod lazy {
316
318
// destructor" flag we just use `mem::replace` which should sequence the
317
319
// operations a little differently and make this safe to call.
318
320
//
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.
324
323
unsafe {
325
324
let _ = mem:: replace ( & mut * ptr, Some ( value) ) ;
326
325
}
327
326
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
333
328
// a `Some` behind `ptr`, not a `None` so `unreachable_unchecked`
334
329
// will never be reached.
335
330
unsafe {
@@ -345,11 +340,12 @@ mod lazy {
345
340
}
346
341
}
347
342
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.
348
346
#[ allow( unused) ]
349
347
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.
353
349
unsafe { ( * self . inner . get ( ) ) . take ( ) }
354
350
}
355
351
}
@@ -442,9 +438,10 @@ pub mod fast {
442
438
// SAFETY: See the definitions of `LazyKeyInner::get` and
443
439
// `try_initialize` for more informations.
444
440
//
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.
448
445
unsafe {
449
446
match self . inner . get ( ) {
450
447
Some ( val) => Some ( val) ,
@@ -549,9 +546,10 @@ pub mod os {
549
546
Key { os : OsStaticKey :: new ( Some ( destroy_value :: < T > ) ) , marker : marker:: PhantomData }
550
547
}
551
548
549
+ /// It is a requirement for the caller to ensure that no mutable
550
+ /// reference is active when this method is called.
552
551
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.
555
553
let ptr = unsafe { self . os . get ( ) as * mut Value < T > } ;
556
554
if ptr as usize > 1 {
557
555
// SAFETY: the check ensured the pointer is safe (its destructor
0 commit comments