Closed
Description
#![feature(const_fn, drop_types_in_const, thread_local_internals)]
type Foo = std::cell::RefCell<String>;
static __KEY: std::thread::__FastLocalKeyInner<Foo> =
std::thread::__FastLocalKeyInner::new();
fn __getit() -> std::option::Option<
&'static std::cell::UnsafeCell<
std::option::Option<Foo>>>
{
__KEY.get()
}
static FOO: std::thread::LocalKey<Foo> =
std::thread::LocalKey::new(__getit, Default::default);
fn main() {
FOO.with(|foo| println!("{}", foo.borrow()));
std::thread::spawn(|| {
FOO.with(|foo| *foo.borrow_mut() += "foo");
}).join().unwrap();
FOO.with(|foo| println!("{}", foo.borrow()));
}
Discovered while working on a sound fix for #17954. The problem is this decision which prevents the thread_local!
macro from using unsafe
to state that it actually has a #[thread_local]
static
to use in LocalKey
. Without that, anything of 'static
lifetime (which is btw quite wrong for #[thread_local]
) and the right type can be used, from safe code.
While we can change the APIs all we want, going back to the correct solution of #[allow(unsafe_code)]
could be a breaking change, without unsafety hygiene.
cc @rust-lang/libs