-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Open
Labels
A-hygieneArea: Macro hygieneArea: Macro hygieneA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-thread-localsArea: Thread local storage (TLS)Area: Thread local storage (TLS)C-bugCategory: This is a bug.Category: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Description
I tried this code:
fn __init() -> u32 {
17
}
const __INIT: u32 = 17;
const VAL: usize = 0;
thread_local! {
static FOO: u32 = __init();
static BAR: u32 = const { __INIT };
static BAZ: [u32; VAL] = const { [] };
}
fn main() {
FOO.with(|&s| assert_eq!(s, 17));
BAR.with(|&s| assert_eq!(s, 17));
BAZ.with(|&s| assert_eq!(s, []));
}
I expected to see this happen: It compiles and runs successfully
Instead, this happened: A bunch of compile errors. If BAR
and BAZ
are commented out, initializing FOO
triggers a stack overflow.
The cause of these issues is shadowing inside thread_local_inner!
. rustc_macro_transparency = "opaque"
should fix it, but is blocked on fixing #146993.
Meta
rustc --version
:
1.92.0-nightly (2025-09-23 975e6c8fec280816d24f)
Backtrace
error[E0391]: cycle detected when computing type of `BAZ::{constant#1}::{closure#0}::VAL`
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
|
note: ...which requires evaluating type-level constant...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires const-evaluating + checking `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires caching mir of `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}` for CTFE...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires elaborating drops for `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires borrow-checking `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires promoting constants in MIR for `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires const checking `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires building MIR for `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires match-checking `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires type-checking `BAZ::{constant#1}::{closure#0}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
= note: ...which again requires computing type of `BAZ::{constant#1}::{closure#0}::VAL`, completing the cycle
note: cycle used when checking that `BAZ::{constant#1}::{closure#0}::VAL` is well-formed
--> src/main.rs:7:1
|
7 | / thread_local! {
8 | | static FOO: u32 = __init();
9 | | static BAR: u32 = const { __INIT };
10 | | static BAZ: [u32; VAL] = const { [] };
11 | | }
| |_^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
= note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0391]: cycle detected when computing type of `BAZ::{constant#1}::{closure#1}::VAL`
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
|
note: ...which requires evaluating type-level constant...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires const-evaluating + checking `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires caching mir of `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}` for CTFE...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires elaborating drops for `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires borrow-checking `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires promoting constants in MIR for `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires const checking `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires building MIR for `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires match-checking `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
note: ...which requires type-checking `BAZ::{constant#1}::{closure#1}::VAL::{constant#0}`...
--> src/main.rs:10:23
|
10 | static BAZ: [u32; VAL] = const { [] };
| ^^^
= note: ...which again requires computing type of `BAZ::{constant#1}::{closure#1}::VAL`, completing the cycle
note: cycle used when checking that `BAZ::{constant#1}::{closure#1}::VAL` is well-formed
--> src/main.rs:7:1
|
7 | / thread_local! {
8 | | static FOO: u32 = __init();
9 | | static BAR: u32 = const { __INIT };
10 | | static BAZ: [u32; VAL] = const { [] };
11 | | }
| |_^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
= note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0391]: cycle detected when simplifying constant for the type system `BAR::__INIT`
--> src/main.rs:7:1
|
7 | / thread_local! {
8 | | static FOO: u32 = __init();
9 | | static BAR: u32 = const { __INIT };
10 | | static BAZ: [u32; VAL] = const { [] };
11 | | }
| |_^
|
note: ...which requires const-evaluating + checking `BAR::__INIT`...
--> src/main.rs:9:31
|
9 | static BAR: u32 = const { __INIT };
| ^^^^^^
= note: ...which again requires simplifying constant for the type system `BAR::__INIT`, completing the cycle
= note: cycle used when running analysis passes on this crate
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
= note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0391`.
@rustbot label T-libs A-macros A-thread-locals A-hygiene
Metadata
Metadata
Assignees
Labels
A-hygieneArea: Macro hygieneArea: Macro hygieneA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-thread-localsArea: Thread local storage (TLS)Area: Thread local storage (TLS)C-bugCategory: This is a bug.Category: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.