Allow elided ('static) lifetimes in thread_local! - #159564
Conversation
with or without a const initializer, on all platforms.
|
r? @JohnTitor rustbot has assigned @JohnTitor. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
Question for reviewer: (how) should I add a test for this? I tried adding a test to attempted UI test// Test each of the three `thread_local!` implementations,
// that it defaults elided lifetimes in the type to `'static`.
// Regression test for 159358.
//@ check-pass
// no-threads
//@ revisions: x86_64-uefi
//@[x86_64-uefi] compile-flags: --target x86_64-unknown-uefi
//@[x86_64-uefi] needs-llvm-components: x86
// target_thread_local
//@ revisions: x86_64-linux
//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu
//@[x86_64-linux] needs-llvm-components: x86
// os
//@ revisions: x86_64-windows-gnu
//@[x86_64-windows-gnu] compile-flags: --target x86_64-pc-windows-gnu
//@[x86_64-windows-gnu] needs-llvm-components: x86
// Const initializer, non-Drop
std::thread_local!(static A: &str = const { "" });
// Non-const initializer, non-Drop
std::thread_local!(static B: &str = "");
fn main() {}( |
#[thread_local]thread_local!
|
@rustbot label T-libs-api I think this needs T-libs-api approval, at least for the non- |
This comment has been minimized.
This comment has been minimized.
It was testing diagnostics emitted for missing lifetime specifiers in `thread_local!`, but now elided lifetimes in `thread_local!` are `'static`, so there's nothing to test.
|
For tests: Hmm, if there's at least one tier-1 target that uses each implementation of |
|
@rustbot reroll |
|
r? libs |
|
I'll nominate for today's libs meeting. @rustbot label:I-libs-nominated |
|
@rfcbot merge libs,libs-api |
|
@Amanieu has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
| // We intentionally have an argument-position `'static` lifetime so that elided lifetimes in `$t` | ||
| // become `'static` like they do for `const`s and `static`s, including in the other two | ||
| // `thread_local!` implementations. | ||
| #[allow(mismatched_lifetime_syntaxes)] | ||
| #[inline] |
There was a problem hiding this comment.
This comment could use a bit more detail, it's quite hard to understand what is actually going on. I'd suggest discussing the concrete example of $t being &str and why the argument matters for that.
There was a problem hiding this comment.
Fair, it took me a bit as a reviewer to understand too. If @zachs18 wants to try and improve the docs before merge I'd be happy to review, otherwise I don't mind improving the docs in a separate PR.
There was a problem hiding this comment.
We still error if the lifetime can't be 'static, right? Is there a test for that?
There was a problem hiding this comment.
Considering the load-bearing:
static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::LazyStorage<$t, ()>uh, yes, if that accepted anything not-'static I would be quite concerned. But I would be happy to add more tests post-merge if it makes you comfortable. Since beta branches today we'll have an entire release cycle to verify there are no issues.
There was a problem hiding this comment.
How's that load-bearing? Seems worth a comment then.
|
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. |
|
@bors try |
This comment has been minimized.
This comment has been minimized.
Allow elided ('static) lifetimes in `thread_local!`
…uwer Rollup of 6 pull requests Successful merges: - #150824 (Document platform-specific behavior of `current_exe`, including that Linux can add `" (deleted)"`) - #159564 (Allow elided ('static) lifetimes in `thread_local!`) - #163026 (hir_typeck: simplify `upvar::determine_capture_info` impl) - #163256 (Document `rustc_abi::VariantLayout`) - #163366 (Stabilize SyncView) - #163376 (Option, Result: not all arguments passed to map_or are eagerly evaluated)
…uwer Rollup of 6 pull requests Successful merges: - #150824 (Document platform-specific behavior of `current_exe`, including that Linux can add `" (deleted)"`) - #159564 (Allow elided ('static) lifetimes in `thread_local!`) - #163026 (hir_typeck: simplify `upvar::determine_capture_info` impl) - #163256 (Document `rustc_abi::VariantLayout`) - #163366 (Stabilize SyncView) - #163376 (Option, Result: not all arguments passed to map_or are eagerly evaluated)
Rollup merge of #159564 - zachs18:fix-159358, r=clarfonthey Allow elided ('static) lifetimes in `thread_local!` with or without a const initializer, on all platforms. Lifetime elision on functions includes named lifetimes and `'static` in input lifetime positions, so if we give the macro-generated `__rust_std_internal_init_fn` function an argument mentioning `'static`, then elided lifetimes in the return type default to `'static`. This uses `PhantomData<&'static ()>` so that it should probably compile down to nothing (at least in release mode). Before this change, elided `'static` lifetimes were allowed only with `const` initializers on the "no-threads" and "native" `thread_local!` implementations, not on the "os" implementation, and not with non-`const` initializers. After this change, they are allowed in all `thread_local!` implementations, with or without a `const` initializer (`A` and `B` both compile on targets with all three `thread_local!` implementations.) ```rs // Const initializer std::thread_local!(static A: &str = const { "" }); // Non-const initializer std::thread_local!(static B: &str = ""); ``` | `thread_local!` implementation | `const` initializer (`A`) | non-`const` initializer (`B`) | | ------------- | ------------- | ---- | | no-threads (e.g. `x86_64-unknown-uefi`) | ✅️ | ❌️ -> ✅️ | | `target_thread_local` (e.g. `x86_64-unknown-linux-gnu`) | ✅️ | ❌️ -> ✅️ | | os (e.g. `x86_64-pc-windows-gnu`) | ❌️ -> ✅️ | ❌️ -> ✅️ | An alternative implementation that would only fix the inconsistency between targets, but not add support for elision with non-`const` initializers, would be to do this same thing, but only on the `os` implementation, and only if the initializer is `const` (i.e. split const initializers to a different macro arm; currently const and non-const initializers generate the same code under the `os` `thread_local!` implementation). Fixes #159538 Fixes #159640 (assuming the non-`const`-initializer part of this PR is not removed)
View all comments
with or without a const initializer, on all platforms.
Lifetime elision on functions includes named lifetimes and
'staticin input lifetime positions, so if we give the macro-generated__rust_std_internal_init_fnfunction an argument mentioning'static, then elided lifetimes in the return type default to'static. This usesPhantomData<&'static ()>so that it should probably compile down to nothing (at least in release mode).Before this change, elided
'staticlifetimes were allowed only withconstinitializers on the "no-threads" and "native"thread_local!implementations, not on the "os" implementation, and not with non-constinitializers.After this change, they are allowed in all
thread_local!implementations, with or without aconstinitializer (AandBboth compile on targets with all threethread_local!implementations.)thread_local!implementationconstinitializer (A)constinitializer (B)x86_64-unknown-uefi)target_thread_local(e.g.x86_64-unknown-linux-gnu)x86_64-pc-windows-gnu)An alternative implementation that would only fix the inconsistency between targets, but not add support for elision with non-
constinitializers, would be to do this same thing, but only on theosimplementation, and only if the initializer isconst(i.e. split const initializers to a different macro arm; currently const and non-const initializers generate the same code under theosthread_local!implementation).Fixes #159538
Fixes #159640 (assuming the non-
const-initializer part of this PR is not removed)