Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions library/std/src/sys/thread_local/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,17 @@ pub macro thread_local_inner {

unsafe {
$crate::thread::LocalKey::new(const {
// We're okay to ignore `__rust_std_internal_init` as we never panic.
if $crate::mem::needs_drop::<$t>() {
|_| {
|__rust_std_internal_init| {
#[thread_local]
$(#[$align_attr])*
static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::EagerStorage<$t>
= $crate::thread::local_impl::EagerStorage::new(__RUST_STD_INTERNAL_INIT);
__RUST_STD_INTERNAL_VAL.get()
}
} else {
|_| {
|__rust_std_internal_init| {
#[thread_local]
$(#[$align_attr])*
static __RUST_STD_INTERNAL_VAL: $t = __RUST_STD_INTERNAL_INIT;
Expand All @@ -92,6 +93,8 @@ pub macro thread_local_inner {

unsafe {
$crate::thread::LocalKey::new(const {
// `__rust_std_internal_init_fn` may panic so we must only call it if there is no
// `__rust_std_internal_init`.
if $crate::mem::needs_drop::<$t>() {
|__rust_std_internal_init| {
#[thread_local]
Expand Down
9 changes: 8 additions & 1 deletion library/std/src/thread/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,14 @@ pub struct LocalKey<T: 'static> {
// 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<&mut Option<T>>) -> *const T,
//
// The argument of the function, `init`, can be used to initialize the key for the current
// thread: if it is not yet initialized, and if the argument is `Some(&mut Some(val))`, the
// inner `val` should be `take`en out and used as the initial value instead of the default.
// Also, in that case `inner` *must not* panic. However, it is okay (but potentially
// inefficient) for `inner` to ignore `init` and use a default value as long as that is
// guaranteed not to panic.
inner: fn(/* init */ Option<&mut Option<T>>) -> *const T,
}

#[stable(feature = "std_debug", since = "1.16.0")]
Expand Down
Loading