Skip to content

In consteval, mixing pointers to the same allocation but with different offsets gives results that depend on a static's address. #146291

@theemathas

Description

@theemathas

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-raw-pointersArea: raw pointers, MaybeUninit, NonNullC-bugCategory: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-opsemRelevant to the opsem teamregression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions