-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Description
Code
I tried this code:
static A: u8 = 123;
const fn mix_ptr() -> *const u8 {
unsafe {
let x: *const u8 = &raw const A;
let mut y = x.wrapping_add(1000000000);
core::ptr::copy_nonoverlapping((&raw const x).cast::<u8>(), (&raw mut y).cast::<u8>(), 4);
y
}
}
fn main() {
let a = const { mix_ptr() };
println!("{a:p}");
let b = mix_ptr();
println!("{b:p}");
assert_eq!(a, b);
}
I expected this to produce a compile error. Instead, in nightly rust, it compiles fine. The resulting program sometimes (but not always) produces an assertion failure.
thread 'main' (174) panicked at src/main.rs:17:5:
assertion `left == right` failed
left: 0x5d65cc756c00
right: 0x5d66cc756c00
(Note that the two pointers differ by exactly 0x100000000
.)
The mix_ptr
function returns a pointer whose high 4 bytes are from (&raw const A).wrapping_add(1000000000)
, and whose low 4 bytes are from &raw const A
.
Consteval seems to be incorrectly assuming that the resulting pointer is equivalent to &raw const A
. This is wrong when the address of A
is within 1000000000 bytes of an address that is a multiple of 2^32
.
Jointly discovered with @HomelikeBrick42
Presumably regressed in #144081. cc @RalfJung
Version it worked on
The above code correctly produces a compiler error on the playground with version 1.90.0-beta.7 (2025-08-29 fb918cec013920472f69)
Version with regression
The above code compiles and has incorrect behavior on the playground with version 1.91.0-nightly (2025-09-06 1ed3cd7030718935a5c5)