I'm not sure if this is a bug, or a surprising behavior caused by #140942.
#[repr(transparent)]
struct SyncPtr(*const ());
unsafe impl Sync for SyncPtr {}
static DATA: () = ();
const MAYBE_NULL: SyncPtr = SyncPtr((&raw const DATA).wrapping_byte_add(8));
static mut YES_MUT: SyncPtr = MAYBE_NULL;
static NOT_MUT: SyncPtr = MAYBE_NULL;
const WORKS: &&() = unsafe { &*(&raw const YES_MUT).cast::<&()>() };
const FAILS: &&() = unsafe { &*(&raw const NOT_MUT).cast::<&()>() };
In the above code, WORKS compiles, but FAILS doesn't. I find this surprising, since, intuitively, a static should be usable in the same way as a static mut that is never mutated. The error message is below:
error[E0080]: constructing invalid value at .<deref>: encountered a null reference
--> src/lib.rs:12:1
|
12 | const FAILS: &&() = unsafe { &*(&raw const NOT_MUT).cast::<&()>() };
| ^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
|
= note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
╾─────alloc5<imm>─────╼ │ ╾──────╼
}
For more information about this error, try `rustc --explain E0080`.
It seems to me that the const validity check performs checks recursively in each const, including through static allocations, but won't recurse through static mut allocations. (Although this explanation seems to contradict how #144719 behaves, where the compiler seems to recurse into a static only once the const is used in a pattern.)
Meta
Reproducible on the playground with version 1.92.0-nightly (2025-09-18 7c275d09ea6b953d2cca)
I'm not sure if this is a bug, or a surprising behavior caused by #140942.
In the above code,
WORKScompiles, butFAILSdoesn't. I find this surprising, since, intuitively, astaticshould be usable in the same way as astatic mutthat is never mutated. The error message is below:It seems to me that the const validity check performs checks recursively in each
const, including throughstaticallocations, but won't recurse throughstatic mutallocations. (Although this explanation seems to contradict how #144719 behaves, where the compiler seems to recurse into a static only once the const is used in a pattern.)Meta
Reproducible on the playground with version
1.92.0-nightly (2025-09-18 7c275d09ea6b953d2cca)