- 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.