]> git.lizzy.rs Git - rust.git/blobdiff - src/libstd/thread/local.rs
Auto merge of #43710 - zackmdavis:field_init_shorthand_power_slam, r=Mark-Simulacrum
[rust.git] / src / libstd / thread / local.rs
index be433e2b81e6b6758ea886803254488d88484718..7a9b642350fa62c10ae7f9174125baf53a07e691 100644 (file)
@@ -91,13 +91,13 @@ pub struct LocalKey<T: 'static> {
     //
     // Note that the thunk is itself unsafe because the returned lifetime of the
     // slot where data lives, `'static`, is not actually valid. The lifetime
-    // here is actually `'thread`!
+    // here is actually slightly shorter than the currently running thread!
     //
     // Although this is an extra layer of indirection, it should in theory be
     // trivially devirtualizable by LLVM because the value of `inner` never
     // changes and the constant should be readonly within a crate. This mainly
     // only runs into problems when TLS statics are exported across crates.
-    inner: fn() -> Option<&'static UnsafeCell<Option<T>>>,
+    inner: unsafe fn() -> Option<&'static UnsafeCell<Option<T>>>,
 
     // initialization routine to invoke to create a value
     init: fn() -> T,
@@ -110,7 +110,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(not(stage0))]
 /// Declare a new thread local storage key of type [`std::thread::LocalKey`].
 ///
 /// # Syntax
@@ -152,19 +151,19 @@ macro_rules! thread_local {
     );
 }
 
-#[cfg(not(stage0))]
 #[doc(hidden)]
 #[unstable(feature = "thread_local_internals",
            reason = "should not be necessary",
            issue = "0")]
 #[macro_export]
 #[allow_internal_unstable]
+#[cfg_attr(not(stage0), allow_internal_unsafe)]
 macro_rules! __thread_local_inner {
     ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
         $(#[$attr])* $vis static $name: $crate::thread::LocalKey<$t> = {
             fn __init() -> $t { $init }
 
-            fn __getit() -> $crate::option::Option<
+            unsafe fn __getit() -> $crate::option::Option<
                 &'static $crate::cell::UnsafeCell<
                     $crate::option::Option<$t>>>
             {
@@ -180,76 +179,13 @@ fn __getit() -> $crate::option::Option<
                 __KEY.get()
             }
 
-            $crate::thread::LocalKey::new(__getit, __init)
+            unsafe {
+                $crate::thread::LocalKey::new(__getit, __init)
+            }
         };
     }
 }
 
-#[cfg(stage0)]
-/// Declare a new thread local storage key of type `std::thread::LocalKey`.
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow_internal_unstable]
-macro_rules! thread_local {
-    // rule 0: empty (base case for the recursion)
-    () => {};
-
-    // rule 1: process multiple declarations where the first one is private
-    ($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
-        thread_local!($(#[$attr])* static $name: $t = $init); // go to rule 2
-        thread_local!($($rest)*);
-    );
-
-    // rule 2: handle a single private declaration
-    ($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr) => (
-        $(#[$attr])* static $name: $crate::thread::LocalKey<$t> =
-            __thread_local_inner!($t, $init);
-    );
-
-    // rule 3: handle multiple declarations where the first one is public
-    ($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
-        thread_local!($(#[$attr])* pub static $name: $t = $init); // go to rule 4
-        thread_local!($($rest)*);
-    );
-
-    // rule 4: handle a single public declaration
-    ($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr) => (
-        $(#[$attr])* pub static $name: $crate::thread::LocalKey<$t> =
-            __thread_local_inner!($t, $init);
-    );
-}
-
-#[cfg(stage0)]
-#[doc(hidden)]
-#[unstable(feature = "thread_local_internals",
-           reason = "should not be necessary",
-           issue = "0")]
-#[macro_export]
-#[allow_internal_unstable]
-macro_rules! __thread_local_inner {
-    ($t:ty, $init:expr) => {{
-        fn __init() -> $t { $init }
-
-        fn __getit() -> $crate::option::Option<
-            &'static $crate::cell::UnsafeCell<
-                $crate::option::Option<$t>>>
-        {
-            #[thread_local]
-            #[cfg(target_thread_local)]
-            static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
-                $crate::thread::__FastLocalKeyInner::new();
-
-            #[cfg(not(target_thread_local))]
-            static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
-                $crate::thread::__OsLocalKeyInner::new();
-
-            __KEY.get()
-        }
-
-        $crate::thread::LocalKey::new(__getit, __init)
-    }}
-}
-
 /// Indicator of the state of a thread local storage key.
 #[unstable(feature = "thread_local_state",
            reason = "state querying was recently added",
@@ -319,11 +255,11 @@ impl<T: 'static> LocalKey<T> {
     #[unstable(feature = "thread_local_internals",
                reason = "recently added to create a key",
                issue = "0")]
-    pub const fn new(inner: fn() -> Option<&'static UnsafeCell<Option<T>>>,
-                     init: fn() -> T) -> LocalKey<T> {
+    pub const unsafe fn new(inner: unsafe fn() -> Option<&'static UnsafeCell<Option<T>>>,
+                            init: fn() -> T) -> LocalKey<T> {
         LocalKey {
-            inner: inner,
-            init: init,
+            inner,
+            init,
         }
     }
 
@@ -458,6 +394,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         }
     }
 
+    #[cfg(stage0)]
     unsafe impl<T> ::marker::Sync for Key<T> { }
 
     impl<T> Key<T> {
@@ -469,14 +406,12 @@ pub const fn new() -> Key<T> {
             }
         }
 
-        pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
-            unsafe {
-                if mem::needs_drop::<T>() && self.dtor_running.get() {
-                    return None
-                }
-                self.register_dtor();
+        pub unsafe fn get(&self) -> Option<&'static UnsafeCell<Option<T>>> {
+            if mem::needs_drop::<T>() && self.dtor_running.get() {
+                return None
             }
-            Some(&self.inner)
+            self.register_dtor();
+            Some(&*(&self.inner as *const _))
         }
 
         unsafe fn register_dtor(&self) {
@@ -545,26 +480,24 @@ pub const fn new() -> Key<T> {
             }
         }
 
-        pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
-            unsafe {
-                let ptr = self.os.get() as *mut Value<T>;
-                if !ptr.is_null() {
-                    if ptr as usize == 1 {
-                        return None
-                    }
-                    return Some(&(*ptr).value);
+        pub unsafe fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
+            let ptr = self.os.get() as *mut Value<T>;
+            if !ptr.is_null() {
+                if ptr as usize == 1 {
+                    return None
                 }
-
-                // If the lookup returned null, we haven't initialized our own
-                // local copy, so do that now.
-                let ptr: Box<Value<T>> = box Value {
-                    key: self,
-                    value: UnsafeCell::new(None),
-                };
-                let ptr = Box::into_raw(ptr);
-                self.os.set(ptr as *mut u8);
-                Some(&(*ptr).value)
+                return Some(&(*ptr).value);
             }
+
+            // If the lookup returned null, we haven't initialized our own
+            // local copy, so do that now.
+            let ptr: Box<Value<T>> = box Value {
+                key: self,
+                value: UnsafeCell::new(None),
+            };
+            let ptr = Box::into_raw(ptr);
+            self.os.set(ptr as *mut u8);
+            Some(&(*ptr).value)
         }
     }