diff options
| author | Alexis Bourget <alexis.bourget@gmail.com> | 2020-08-29 20:10:05 +0200 |
|---|---|---|
| committer | Alexis Bourget <alexis.bourget@gmail.com> | 2020-09-21 22:37:30 +0200 |
| commit | 5d29954b2f2c3e079372bbaaee2ed64c1674046b (patch) | |
| tree | b898df085c395048304a428aaa813da705613e8e /library/std/src/thread | |
| parent | a83b79ec31df3a467753c3e5b41cf457af544c7b (diff) | |
| download | rust-5d29954b2f2c3e079372bbaaee2ed64c1674046b.tar.gz rust-5d29954b2f2c3e079372bbaaee2ed64c1674046b.zip | |
Improve some SAFETY comments following suggestions
Diffstat (limited to 'library/std/src/thread')
| -rw-r--r-- | library/std/src/thread/local.rs | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 281e1ef6741..54efff2a92b 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -315,12 +315,23 @@ mod lazy { // value (an aliasing violation). To avoid setting the "I'm running a // destructor" flag we just use `mem::replace` which should sequence the // operations a little differently and make this safe to call. + // + // `ptr` can be dereferenced safely since it was obtained from + // `UnsafeCell::get`, which should not return a non-aligned or NUL pointer. + // What's more a `LazyKeyInner` can only be created with `new`, which ensures + // `inner` is correctly initialized and all calls to methods on `LazyKeyInner` + // will leave `inner` initialized too. unsafe { let _ = mem::replace(&mut *ptr, Some(value)); } - // SAFETY: the *ptr operation is made safe by the `mem::replace` - // call above that made sure a valid value is present behind it. + // SAFETY: the `*ptr` operation is made safe by the `mem::replace` + // call above combined with `ptr` being correct from the beginning + // (see previous SAFETY: comment above). + // + // Plus, with the call to `mem::replace` it is guaranteed there is + // a `Some` behind `ptr`, not a `None` so `unreachable_unchecked` + // will never be reached. unsafe { // After storing `Some` we want to get a reference to the contents of // what we just stored. While we could use `unwrap` here and it should @@ -337,8 +348,8 @@ mod lazy { #[allow(unused)] pub unsafe fn take(&mut self) -> Option<T> { // SAFETY: The other methods hand out references while taking &self. - // As such, calling this method when such references are still alive - // will fail because it takes a &mut self, conflicting with them. + // As such, callers of this method must ensure no `&` and `&mut` are + // available and used at the same time. unsafe { (*self.inner.get()).take() } } } @@ -451,9 +462,9 @@ pub mod fast { // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722 #[inline(never)] unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> { - // SAFETY: See comment above. + // SAFETY: See comment above (this function doc). if !mem::needs_drop::<T>() || unsafe { self.try_register_dtor() } { - // SAFETY: See comment above. + // SAFETY: See comment above (his function doc). Some(unsafe { self.inner.initialize(init) }) } else { None |
