Closed
Description
This code makes the compiler report undefined behavior in safe code during consteval.
use std::cell::UnsafeCell;
const X: &mut UnsafeCell<[i32]> = UnsafeCell::from_mut(&mut []);
error[E0080]: constructing invalid value at .<deref>: encountered `UnsafeCell` in read-only memory
--> src/lib.rs:2:1
|
2 | const X: &mut UnsafeCell<[i32]> = UnsafeCell::from_mut(&mut []);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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: 16, align: 8) {
╾───────alloc3────────╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
}
For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground` (lib) due to 1 previous error
UnsafeCell::from_mut
has been stable in const since 1.84.0. The similar Cell::from_mut
is about to be stabilized in const in 1.88.0, which is in a couple days. Using Cell
instead of UnsafeCell
results in a similar error.
Code using Cell
use std::cell::Cell;
const X: &Cell<[i32]> = Cell::from_mut(&mut []);
error[E0080]: constructing invalid value at .<deref>.value: encountered `UnsafeCell` in read-only memory
--> src/lib.rs:2:1
|
2 | const X: &Cell<[i32]> = Cell::from_mut(&mut []);
| ^^^^^^^^^^^^^^^^^^^^^ 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: 16, align: 8) {
╾───────alloc3────────╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
}
For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground` (lib) due to 1 previous error
Note that this issue only happens if there's an unsize coercion from [T; 0]
to [T]
. That is, the following code compiles fine:
use std::cell::UnsafeCell;
const X: &mut UnsafeCell<[i32; 0]> = UnsafeCell::from_mut(&mut []);
Note that storing a &mut
in a const in safe code is only possible on empty arrays. See #140126.
Meta
Reproducible on the playground with 1.90.0-nightly (2025-06-23 706f244db581212cabf2)
@rustbot labels +A-const-eval +I-unsound