Code change:
/// information. #[macro_export] #[allow_internal_unstable] <del> #[cfg(not(no_elf_tls))] </del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); (pub static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> pub static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); } <ins> #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] </ins> #[macro_export] #[allow_internal_unstable] #[cfg(no_elf_tls)] <del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); (pub static $name:ident: $t:ty) => ( pub static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); </del> <ins> macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} } #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] #[macro_export] #[allow_internal_unstable] #[cfg(not(no_elf_tls))] macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} </ins> } #[unstable(feature = "scoped_tls",

Related discussion:
text: There is an  in the scoped TLS module, which allows for sharing of data that wasn't meant to be shared. An unqualified should only_ be used when provides some sort of threadsafe locking mechanism. and do not. This lets us, for example, clone an or between threads, in safe code: Here, we have clones from different threads being interleaved, which can cause unsafety if there's a race on the refcount. We could also cause unsafety with a , or any other non-Sync type. basically lets us share across threads even if . I put the sleeps in there because somehow without them the routines are run serially. Note that this is not a problem with the API. I'm using here because to exploit one needs to be able to share across threads, and has an additional bound which doesn't satisfy. Any usable API will probably have to make the assumption that . Nor is this a problem with , since it can be done with , too. Solution: Make it ... I think. I'm not familiar with this API, and I'm not sure why it's even in the first place.
cc
cc This seems concerning: this is designed to be thread-local, so that e.g. storing a works (which would be safe, if it were guaranteed to stay on one thread). However currently requires unconditionally, hence this overly-accepting impl.
Qualifying the impl with breaks scoped TLS for (see the associated PR); because becomes no longer and thus can't be stuffed inside a static.
I believe the only way statics can be safe is by requiring the absence of Sync. That may sound odd, but consider the following: - sending thread-local references across threads is memory unsafe even with no interior mutability a static with no interior mutability is almost entirely useless, certainly not a common case non- containers offering interior mutabilities are cheaper and preferred to ones, where they can be used The main issue is actually within the libstd TLS implementation: is a wrapper for getters so it's unaffected by it, but may live in a static or a global one, depending on whether the platform natively supports TLS or not. -ing a across threads is actually safe on the architectures which do not have native TLS support. However, allowing it on some architectures and not on others is undesirable. Should use an accessor model like ?