-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Open
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.Category: This is a bug.T-langRelevant to the language teamRelevant to the language teamT-opsemRelevant to the opsem teamRelevant to the opsem teamneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.
Description
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)
Metadata
Metadata
Assignees
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.Category: This is a bug.T-langRelevant to the language teamRelevant to the language teamT-opsemRelevant to the opsem teamRelevant to the opsem teamneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.