Don't claim `LocalKey::with` prevents a reference to be sent across threads
The documentation for `LocalKey` claims that `with` yields a reference that cannot be sent across threads, but this is false since you can easily do that with scoped threads. What it actually prevents is the reference from outliving the current thread.
This allows removing all the platform-dependent code from `library/std/src/thread/local.rs` and `library/std/src/thread/mod.rs`
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
Move __thread_local_inner macro in crate:🧵:local to crate::sys.
Currently, the tidy check does not fail for `library/std/src/thread/local.rs` even though it contains platform specific code. This is beacause target_family did not exist at the time the tidy checks were written [1].
[1]: https://github.com/rust-lang/rust/pull/105861#discussion_r1125841678
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
std: Stabilize the `thread_local_const_init` feature
This commit is intended to follow the stabilization disposition of the
FCP that has now finished in #84223. This stabilizes the ability to flag
thread local initializers as `const` expressions which enables the macro
to generate more efficient code for accessing it, notably removing
runtime checks for initialization.
More information can also be found in #84223 as well as the tests where
the feature usage was removed in this PR.
Closes#84223
This commit is intended to follow the stabilization disposition of the
FCP that has now finished in #84223. This stabilizes the ability to flag
thread local initializers as `const` expressions which enables the macro
to generate more efficient code for accessing it, notably removing
runtime checks for initialization.
More information can also be found in #84223 as well as the tests where
the feature usage was removed in this PR.
Closes#84223
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
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
This commit goes through and updates various `#[cfg]` as appropriate to
get the wasm64-unknown-unknown target behaving similarly to the
wasm32-unknown-unknown target. Most of this is just updating various
conditions for `target_arch = "wasm32"` to also account for `target_arch
= "wasm64"` where appropriate. This commit also lists `wasm64` as an
allow-listed architecture to not have the `restricted_std` feature
enabled, enabling experimentation with `-Z build-std` externally.
The main goal of this commit is to enable playing around with
`wasm64-unknown-unknown` externally via `-Z build-std` in a way that's
similar to the `wasm32-unknown-unknown` target. These targets are
effectively the same and only differ in their pointer size, but wasm64
is much newer and has much less ecosystem/library support so it'll still
take time to get wasm64 fully-fledged.
Due to the std/alloc split, it is not possible to make
`alloc::collections::TryReserveError::AllocError` non-exhaustive without
having an unstable, doc-hidden method to construct (which negates the
benefits from `#[non_exhaustive]`.
Issue #25088 has been part of `thread_local!` for quite some time now.
Historical attempts have been made to add `#[inline]` to `__getit`
in #43931, #50252, and #59720, but these attempts ended up not landing
at the time due to segfaults on Windows.
In the interim though with `const`-initialized thread locals AFAIK this
is the only remaining bug which is why you might want to use
`#[thread_local]` over `thread_local!`. As a result I figured it was
time to resubmit this and see how it fares on CI and if I can help
debugging any issues that crop up.
Closes#25088
Replace all `fmt.pad` with `debug_struct`
This replaces any occurrence of:
- `f.pad("X")` with `f.debug_struct("X").finish()`
- `f.pad("X { .. }")` with `f.debug_struct("X").finish_non_exhaustive()`
This is in line with existing formatting code such as
1255053067/library/std/src/sync/mpsc/mod.rs (L1470-L1475)
This commit adds a variant of the `thread_local!` macro as a new
`thread_local_const_init!` macro which requires that the initialization
expression is constant (e.g. could be stuck into a `const` if so
desired). This form of thread local allows for a more efficient
implementation of `LocalKey::with` both if the value has a destructor
and if it doesn't. If the value doesn't have a destructor then `with`
should desugar to exactly as-if you use `#[thread_local]` given
sufficient inlining.
The purpose of this new form of thread locals is to precisely be
equivalent to `#[thread_local]` on platforms where possible for values
which fit the bill (those without destructors). This should help close
the gap in performance between `thread_local!`, which is safe, relative
to `#[thread_local]`, which is not easy to use in a portable fashion.