rust-lang / rust-lang/rust

Casts between floats and ints fail to roundtrip properly on `i586-unknown-linux-gnu`

Open
#152,635 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-floating-point A-LLVM C-bug O-x86_32 T-compiler
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

Doc tests introduced in https://github.com/rust-lang/rust/pull/152512 for f32 and f64 failed in a rollup https://github.com/rust-lang/rust/pull/152616#issuecomment-3902253969 on the i586-unknown-linux-gnu job.

These tests as cast between i32<->f32 and i64<->f64, with no floating point arithmetic performed.

I tried this code:

{ // Max exact integer test, f32
let max_exact_int: i32 = (1 << f32::MANTISSA_DIGITS) - 1;
assert_eq!(max_exact_int, max_exact_int as f32 as i32);
assert_eq!(max_exact_int + 1, (max_exact_int + 1) as f32 as i32);
assert_ne!(max_exact_int + 2, (max_exact_int + 2) as f32 as i32);
// Beyond `f32::MAX_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((max_exact_int + 1) as f32, (max_exact_int + 2) as f32);
}

{ // Min exact integer test, f32
let min_exact_int: i32 = -((1 << f32::MANTISSA_DIGITS) - 1);
assert_eq!(min_exact_int, min_exact_int as f32 as i32);
assert_eq!(min_exact_int - 1, (min_exact_int - 1) as f32 as i32);
assert_ne!(min_exact_int - 2, (min_exact_int - 2) as f32 as i32);
// Below `f32::MIN_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((min_exact_int - 1) as f32, (min_exact_int - 2) as f32);
}

{ // Max exact integer test, f64
let max_exact_int: i64 = (1 << f64::MANTISSA_DIGITS) - 1;
assert_eq!(max_exact_int, max_exact_int as f64 as i64);
assert_eq!(max_exact_int + 1, (max_exact_int + 1) as f64 as i64);
assert_ne!(max_exact_int + 2, (max_exact_int + 2) as f64 as i64);
// Beyond `f64::MAX_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((max_exact_int + 1) as f64, (max_exact_int + 2) as f64);
}

{ // Min exact integer test, f64
let min_exact_int: i64 = -((1 << f64::MANTISSA_DIGITS) - 1);
assert_eq!(min_exact_int, min_exact_int as f64 as i64);
assert_eq!(min_exact_int - 1, (min_exact_int - 1) as f64 as i64);
assert_ne!(min_exact_int - 2, (min_exact_int - 2) as f64 as i64);
// Below `f64::MIN_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((min_exact_int - 1) as f64, (min_exact_int - 2) as f64);
}

I expected to see this happen: All 4 of these test blocks should pass

Instead, this happened: All 4 blocks failed

Probably related to https://github.com/rust-lang/rust/issues/114479

Meta

I didn't see the toolchain in the log, but whatever tip of nightly was at 2026-02-14T16:31:07.2087585Z

Backtrace

---
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i32, i32>
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:394:5
   4: rust_out::main::_doctest_main_library_core_src_num_f32_rs_528_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f32.rs - f32::f32::MAX_EXACT_INTEGER (line 528) stdout end ----
---
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i32, i32>
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:394:5
   4: rust_out::main::_doctest_main_library_core_src_num_f32_rs_555_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f32.rs - f32::f32::MIN_EXACT_INTEGER (line 555) stdout end ----
---
   1: core::panicking::panic_fmt
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i64, i64>
   4: rust_out::main::_doctest_main_library_core_src_num_f64_rs_527_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f64.rs - f64::f64::MAX_EXACT_INTEGER (line 527) stdout end ----
---
   1: core::panicking::panic_fmt
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i64, i64>
   4: rust_out::main::_doctest_main_library_core_src_num_f64_rs_554_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f64.rs - f64::f64::MIN_EXACT_INTEGER (line 554) stdout end ----

@rustbot label A-floating-point O-x86_32

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

Run the four doctests in library/core/src/num/f32.rs and library/core/src/num/f64.rs on the i586-unknown-linux-gnu job, using the failing assertions and backtrace as the starting point. Read the related issue #114479 to understand the cast behavior being investigated. Done means all four integer-to-float-to-integer roundtrip test blocks pass on that target.

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
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.