Skip to content

Rust unable to compare two numbers in --release mode (miscompile?) #141021

Closed as duplicate of#107975
@ThomasHabets

Description

@ThomasHabets

In release mode assert_eq!() fails on two numbers that in fact are the same.

I tried this code

I have a case where I create two entangled particles. They have some shared Arc unknown state. If you ask the state, or each particle for their id, they will all reply with the same number, generated by the entangled state.

use std::sync::Arc;
struct Unknown {
}
impl Unknown {
    fn id(&self) -> u64 {
        &self as *const _ as u64
    }
}
struct Particle {
    s: Arc<Unknown>,
}
impl Particle {
    fn id(&self) -> u64 {
        self.s.id()
    }
}
fn create() -> (Particle, Particle) {
    let s = Arc::new(Unknown{});
    (Particle{s: s.clone()}, Particle{s})
}

fn main() {
    let (left, right) = create();
    assert_eq!(left.id(), right.id());
}

I expected to see this happen

The assert_eq! to succeed, since the numbers are definitely the same.

Instead, this happened

Works in debug build, asserts in release build:

$ cargo run --verbose
       Dirty bad v0.1.0 (/home/thomas/tmp/bad): the file `src/main.rs` has changed (1747289904.616906220s, 3m 43s after last build at 1747289681.264659271s)
   Compiling bad v0.1.0 (/home/thomas/tmp/bad)
     Running `/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name bad --edition=2024 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=225 --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=74ea956b76c91b92 -C extra-filename=-0fc67055542ffac8 --out-dir /home/thomas/tmp/bad/target/debug/deps -C incremental=/home/thomas/tmp/bad/target/debug/incremental -L dependency=/home/thomas/tmp/bad/target/debug/deps -Ctarget-cpu=native`
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
     Running `target/debug/bad`
$ cargo run --release --verbose
       Dirty bad v0.1.0 (/home/thomas/tmp/bad): the file `src/main.rs` has changed (1747289904.616906220s, 3m 39s after last build at 1747289685.924665034s)
   Compiling bad v0.1.0 (/home/thomas/tmp/bad)
     Running `/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name bad --edition=2024 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=225 --crate-type bin --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=47dd865bb155b0dd -C extra-filename=-a3db58b646f52598 --out-dir /home/thomas/tmp/bad/target/release/deps -C strip=debuginfo -L dependency=/home/thomas/tmp/bad/target/release/deps -Ctarget-cpu=native`
    Finished `release` profile [optimized] target(s) in 0.09s
     Running `target/release/bad`

thread 'main' panicked at src/main.rs:24:5:
assertion `left == right` failed
  left: 140725163265000
 right: 140725163265000
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

These numbers are the same. I was going crazy for a bit. I even changed the code to:

 let (a,b) = (left.id(), right.id());
 assert_eq!(a,b, "the difference is: {}", a-b);

and then I get:

thread 'main' panicked at src/main.rs:25:5:
assertion `left == right` failed: the difference is: 0
  left: 140721109877640
 right: 140721109877640

Note the difference is: 0.

Meta

$ cargo version --verbose
rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-unknown-linux-gnu
release: 1.86.0
LLVM version: 19.1.7

Also same thing on nightly:
$ cargo +nightly version --verbose 
cargo 1.89.0-nightly (7918c7eb5 2025-04-27)
release: 1.89.0-nightly
commit-hash: 7918c7eb59614c39f1c4e27e99d557720976bdd7
commit-date: 2025-04-27
host: x86_64-unknown-linux-gnu
libgit2: 1.9.0 (sys:0.20.0 vendored)
libcurl: 8.12.1-DEV (sys:0.4.80+curl-8.12.1 vendored ssl:OpenSSL/3.4.1)
ssl: OpenSSL 3.4.1 11 Feb 2025
os: Debian 12.0.0 (bookworm) [64-bit]

After a rustup update, problem remains:

cargo 1.89.0-nightly (056f5f4f3 2025-05-09)
release: 1.89.0-nightly
commit-hash: 056f5f4f3c100cb36b5e9aed2d20b9ea70aae295
commit-date: 2025-05-09
host: x86_64-unknown-linux-gnu
libgit2: 1.9.0 (sys:0.20.0 vendored)
libcurl: 8.12.1-DEV (sys:0.4.80+curl-8.12.1 vendored ssl:OpenSSL/3.4.1)
ssl: OpenSSL 3.4.1 11 Feb 2025
os: Debian 12.0.0 (bookworm) [64-bit]

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-discussionCategory: Discussion or questions that doesn't represent real issues.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions