about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-27 07:28:53 +0000
committerbors <bors@rust-lang.org>2024-04-27 07:28:53 +0000
commit35194e76b769d57ecb243b202228cce24158041b (patch)
tree1a84579816f61172461b61ea83a7d6cf9c49d87e /library/std/src
parent9ac33d9c33741fc24a2ff4a177e72f31b9dc775f (diff)
parent9a6bfc7bfc6f297a052bbd7dede11dabc9e5daac (diff)
Auto merge of #124428 - matthiaskrgr:rollup-sk5z4z8, r=matthiaskrgr
Rollup of 3 pull requests

Successful merges:

 - #124382 (ast: Generalize item kind visiting)
 - #124387 (thread_local: be excruciatingly explicit in dtor code)
 - #124427 (Add missing tests for an ICE)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sys/thread_local/fast_local.rs7
-rw-r--r--library/std/src/sys/thread_local/mod.rs14
2 files changed, 12 insertions, 9 deletions
diff --git a/library/std/src/sys/thread_local/fast_local.rs b/library/std/src/sys/thread_local/fast_local.rs
index 69ee70de30c..49b51a729e4 100644
--- a/library/std/src/sys/thread_local/fast_local.rs
+++ b/library/std/src/sys/thread_local/fast_local.rs
@@ -1,7 +1,7 @@
 use super::lazy::LazyKeyInner;
 use crate::cell::Cell;
 use crate::sys::thread_local_dtor::register_dtor;
-use crate::{fmt, mem, panic};
+use crate::{fmt, mem, panic, ptr};
 
 #[doc(hidden)]
 #[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
@@ -237,8 +237,9 @@ unsafe extern "C" fn destroy_value<T>(ptr: *mut u8) {
     // Wrap the call in a catch to ensure unwinding is caught in the event
     // a panic takes place in a destructor.
     if let Err(_) = panic::catch_unwind(panic::AssertUnwindSafe(|| unsafe {
-        let value = (*ptr).inner.take();
-        (*ptr).dtor_state.set(DtorState::RunningOrHasRun);
+        let Key { inner, dtor_state } = &*ptr;
+        let value = inner.take();
+        dtor_state.set(DtorState::RunningOrHasRun);
         drop(value);
     })) {
         rtabort!("thread local panicked on drop");
diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs
index 8b2c839f837..7500c95d8b4 100644
--- a/library/std/src/sys/thread_local/mod.rs
+++ b/library/std/src/sys/thread_local/mod.rs
@@ -91,13 +91,15 @@ mod lazy {
             }
         }
 
-        /// The other methods hand out references while taking &self.
-        /// As such, callers of this method must ensure no `&` and `&mut` are
-        /// available and used at the same time.
+        /// Watch out: unsynchronized internal mutability!
+        ///
+        /// # Safety
+        /// Causes UB if any reference to the value is used after this.
         #[allow(unused)]
-        pub unsafe fn take(&mut self) -> Option<T> {
-            // SAFETY: See doc comment for this method.
-            unsafe { (*self.inner.get()).take() }
+        pub(crate) unsafe fn take(&self) -> Option<T> {
+            let mutable: *mut _ = UnsafeCell::get(&self.inner);
+            // SAFETY: That's the caller's problem.
+            unsafe { mutable.replace(None) }
         }
     }
 }