From 1ac5d7dcde57c3f4baa975d79dbdb57dfdb2489c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 10 Nov 2021 10:55:30 -0800 Subject: [PATCH] std: Tweak expansion of thread-local const This commit tweaks the expansion of `thread_local!` when combined with a `const { ... }` value to help ensure that the rules which apply to `const { ... }` blocks will be the same as when they're stabilized. Previously with this invocation: thread_local!(static NAME: Type = const { init_expr }); this would generate (on supporting platforms): #[thread_local] static NAME: Type = init_expr; instead the macro now expands to: const INIT_EXPR: Type = init_expr; #[thread_local] static NAME: Type = INIT_EXPR; with the hope that because `init_expr` is defined as a `const` item then it's not accidentally allowing more behavior than if it were put into a `static`. For example on the stabilization issue [this example][ex] now gives the same error both ways. [ex]: https://github.com/rust-lang/rust/issues/84223#issuecomment-953384298 --- library/std/src/thread/local.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index c53290ec0c7..b27db876176 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -165,6 +165,7 @@ macro_rules! __thread_local_inner { #[cfg_attr(not(windows), inline)] // see comments below unsafe fn __getit() -> $crate::option::Option<&'static $t> { const _REQUIRE_UNSTABLE: () = $crate::thread::require_unstable_const_init_thread_local(); + const INIT_EXPR: $t = $init; // wasm without atomics maps directly to `static mut`, and dtors // aren't implemented because thread dtors aren't really a thing @@ -174,7 +175,7 @@ macro_rules! __thread_local_inner { // block. #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] { - static mut VAL: $t = $init; + static mut VAL: $t = INIT_EXPR; Some(&VAL) } @@ -184,18 +185,17 @@ macro_rules! __thread_local_inner { not(all(target_arch = "wasm32", not(target_feature = "atomics"))), ))] { + #[thread_local] + static mut VAL: $t = INIT_EXPR; + // If a dtor isn't needed we can do something "very raw" and // just get going. if !$crate::mem::needs_drop::<$t>() { - #[thread_local] - static mut VAL: $t = $init; unsafe { return Some(&VAL) } } - #[thread_local] - static mut VAL: $t = $init; // 0 == dtor not registered // 1 == dtor registered, dtor not run // 2 == dtor registered and is running or has run @@ -242,7 +242,7 @@ macro_rules! __thread_local_inner { ))] { #[inline] - const fn __init() -> $t { $init } + const fn __init() -> $t { INIT_EXPR } static __KEY: $crate::thread::__OsLocalKeyInner<$t> = $crate::thread::__OsLocalKeyInner::new(); #[allow(unused_unsafe)]