rust-lang / rust-lang/rust

`unsized_const_params` pointer identity is nondeterministic with incremental compilation

Open
#153,168 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-const-eval A-incr-comp A-monomorphization A-raw-pointers A-reproducibility C-bug F-unsized_const_params S-has-mcve T-compiler T-lang T-opsem
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the alternating src/lib1.rs and src/lib2.rs files and the provided cargo +nightly build script. Start by investigating incremental compilation's handling of pointer identity for the const-generic calls, then verify that repeated builds consistently produce the same result for FAILS rather than alternating between success and E0080.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.