Skip to content

unsized_const_params pointer identity is nondeterministic with incremental compilation #153168

@theemathas

Description

@theemathas

This issue is a consequence of #120961. cc @RalfJung @BoxyUwU

I have the following code in src/lib1.rs:

#![feature(adt_const_params, unsized_const_params)]
#![expect(incomplete_features)]

static DATA: u8 = 1;

const PTR: &u8 = &DATA;

const fn foo<const N: &'static u8, T>() -> *const u8 {
    N
}

const LOL: *const u8 = foo::<PTR, i32>();

pub struct Dummy<T>(T);
impl<T> Dummy<T> {
    const C: () = unsafe {
        foo::<PTR, T>().offset_from(foo::<PTR, T>());
    };
    const D: () = unsafe {
        foo::<PTR, T>().offset_from(LOL);
    };
}

pub const WORKS: () = Dummy::<i32>::C;
pub const FAILS: () = Dummy::<i32>::D;

I have the identical code in src/lib2.rs, except that D is declared as public.

contents of lib2.rs
#![feature(adt_const_params, unsized_const_params)]
#![expect(incomplete_features)]

static DATA: u8 = 1;

const PTR: &u8 = &DATA;

const fn foo<const N: &'static u8, T>() -> *const u8 {
    N
}

const LOL: *const u8 = foo::<PTR, i32>();

pub struct Dummy<T>(T);
impl<T> Dummy<T> {
    const C: () = unsafe {
        foo::<PTR, T>().offset_from(foo::<PTR, T>());
    };
    pub const D: () = unsafe {
        foo::<PTR, T>().offset_from(LOL);
    };
}

pub const WORKS: () = Dummy::<i32>::C;
pub const FAILS: () = Dummy::<i32>::D;

I then alternate between compiling lib1.rs and lib2.rs with the following script.

#!/usr/bin/env sh

cargo +nightly clean
echo 'Compiling lib1'
cp src/lib1.rs src/lib.rs
cargo +nightly build
echo 'Compiling lib2'
cp src/lib2.rs src/lib.rs
cargo +nightly build
echo 'Compiling lib1'
cp src/lib1.rs src/lib.rs
cargo +nightly build
echo 'Compiling lib2'
cp src/lib2.rs src/lib.rs
cargo +nightly build
echo 'Compiling lib1'
cp src/lib1.rs src/lib.rs
cargo +nightly build
echo 'Compiling lib2'
cp src/lib2.rs src/lib.rs
cargo +nightly build

The compiler switches back and forth between report whether the FAILS const has UB or not. The compiler seems to have a pattern of having two successful compilation followed by one failed compilation, and repeating.

Output of running the above script
     Removed 0 files
Compiling lib1
   Compiling foo v0.1.0 (/Users/timch/foo)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
Compiling lib2
   Compiling foo v0.1.0 (/Users/timch/foo)
error[E0080]: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
   --> src/lib.rs:20:9
    |
 20 |         foo::<PTR, T>().offset_from(LOL);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Dummy::<i32>::D` failed inside this call
    |
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:619:18
    |
619 |         unsafe { intrinsics::ptr_offset_from(self, origin) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here

note: erroneous constant encountered
  --> src/lib.rs:25:23
   |
25 | pub const FAILS: () = Dummy::<i32>::D;
   |                       ^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0080`.
error: could not compile `foo` (lib) due to 1 previous error
Compiling lib1
   Compiling foo v0.1.0 (/Users/timch/foo)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Compiling lib2
   Compiling foo v0.1.0 (/Users/timch/foo)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Compiling lib1
   Compiling foo v0.1.0 (/Users/timch/foo)
error[E0080]: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
   --> src/lib.rs:20:9
    |
 20 |         foo::<PTR, T>().offset_from(LOL);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Dummy::<i32>::D` failed inside this call
    |
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:619:18
    |
619 |         unsafe { intrinsics::ptr_offset_from(self, origin) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here

note: erroneous constant encountered
  --> src/lib.rs:25:23
   |
25 | pub const FAILS: () = Dummy::<i32>::D;
   |                       ^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0080`.
error: could not compile `foo` (lib) due to 1 previous error
Compiling lib2
   Compiling foo v0.1.0 (/Users/timch/foo)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s

Having code nondeterministically compile or error seems bad.

Meta

rustc --version --verbose:

rustc 1.95.0-nightly (6a979b3e3 2026-02-26)
binary: rustc
commit-hash: 6a979b3e32522049d0acb4a47f7ae44b7c8abfd5
commit-date: 2026-02-26
host: aarch64-apple-darwin
release: 1.95.0-nightly
LLVM version: 22.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-incr-compArea: Incremental compilationA-monomorphizationArea: MonomorphizationA-raw-pointersArea: raw pointers, MaybeUninit, NonNullA-reproducibilityArea: Reproducible / deterministic buildsC-bugCategory: This is a bug.F-unsized_const_params`#![feature(unsized_const_params)]`S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions