-
Notifications
You must be signed in to change notification settings - Fork 13.4k
std::thread::local internals allow race conditions in safe but unstable code. #43733
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
We can probably introduce a way for |
@Manishearth Exactly my thoughts but it'd be nice if we had |
A slight hole in that would be that now user-written unsafe code in ....... I'm not sure what to do about that. |
@Manishearth |
Oh, right! |
@arielb1 suggested using item hygiene from the new macros. So I added So |
|
Check #[thread_local] statics correctly in the compiler. Fixes #43733 by introducing `#[allow_internal_unsafe]` analogous to `#[allow_internal_unstable]`, for letting a macro expand to `unsafe` blocks and functions even in `#![forbid(unsafe_code)]` crates. Fixes #17954 by not letting references to `#[thread_local]` statics escape the function they're taken in - we can't just use a magical lifetime because Rust has *lifetime parametrism*, so if we added the often-proposed `'thread` lifetime, we'd have no way to check it in generic code. To avoid potential edge cases in the compiler, the lifetime is actually that of a temporary at the same position, i.e. `&TLS_STATIC` has the same lifetime `&non_const_fn()` would. Referring to `#[thread_local]` `static`s at compile-time is banned now (as per PR discussion). Additionally, to remove `unsafe impl Sync` from `std::thread::local::fast::Key`, `#[thread_local]` statics are now not required to implement `Sync`, as they are not shared between threads.
Check #[thread_local] statics correctly in the compiler. Fixes #43733 by introducing `#[allow_internal_unsafe]` analogous to `#[allow_internal_unstable]`, for letting a macro expand to `unsafe` blocks and functions even in `#![forbid(unsafe_code)]` crates. Fixes #17954 by not letting references to `#[thread_local]` statics escape the function they're taken in - we can't just use a magical lifetime because Rust has *lifetime parametrism*, so if we added the often-proposed `'thread` lifetime, we'd have no way to check it in generic code. To avoid potential edge cases in the compiler, the lifetime is actually that of a temporary at the same position, i.e. `&TLS_STATIC` has the same lifetime `&non_const_fn()` would. Referring to `#[thread_local]` `static`s at compile-time is banned now (as per PR discussion). Additionally, to remove `unsafe impl Sync` from `std::thread::local::fast::Key`, `#[thread_local]` statics are now not required to implement `Sync`, as they are not shared between threads.
(try on playpen)
Discovered while working on a sound fix for #17954. The problem is this decision which prevents the
thread_local!
macro from usingunsafe
to state that it actually has a#[thread_local]
static
to use inLocalKey
. 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
The text was updated successfully, but these errors were encountered: