num-traits
num-traits copied to clipboard
`cast_float_to_int_edge_cases` fails on Debian / mips & mipsel
Full log: https://buildd.debian.org/status/fetch.php?pkg=rust-num-traits&arch=mipsel&ver=0.2.15-1&stamp=1654173339&raw=0
failures:
---- cast_float_to_int_edge_cases stdout ----
testing cast edge cases for f32 -> isize
testing min -2147483648
vs. -2147483648
and -2147483904
testing max 2147483520
vs. 2147483520
and 2147483648
testing non-finite values
testing cast edge cases for f32 -> i8
testing min -128
vs. -129
and -129
testing max 127
vs. 128
and 128
testing non-finite values
testing cast edge cases for f32 -> i16
testing min -32768
vs. -32769
and -32769
testing max 32767
vs. 32768
and 32768
testing non-finite values
testing cast edge cases for f32 -> i32
testing min -2147483648
vs. -2147483648
and -2147483904
testing max 2147483520
vs. 2147483520
and 2147483648
testing non-finite values
testing cast edge cases for f32 -> i64
testing min -9223372036854775808
vs. -9223372036854775808
and -9223373136366403584
testing max 9223371487098961920
vs. 9223371487098961920
and 9223372036854775808
testing non-finite values
testing cast edge cases for f32 -> usize
testing min 0
vs. -1
and -1
testing max 4294967040
vs. 4294967040
and 4294967296
testing non-finite values
testing cast edge cases for f32 -> u8
testing min 0
vs. -1
and -1
testing max 255
vs. 256
and 256
testing non-finite values
testing cast edge cases for f32 -> u16
testing min 0
vs. -1
and -1
testing max 65535
vs. 65536
and 65536
testing non-finite values
testing cast edge cases for f32 -> u32
testing min 0
vs. -1
and -1
testing max 4294967040
vs. 4294967040
and 4294967296
testing non-finite values
testing cast edge cases for f32 -> u64
testing min 0
vs. -1
and -1
testing max 18446742974197923840
vs. 18446742974197923840
and 18446744073709551616
testing non-finite values
testing cast edge cases for f64 -> isize
testing min -2147483648
vs. -2147483649
and -2147483649
thread 'cast_float_to_int_edge_cases' panicked at 'assertion failed: `(left == right)`
left: `Some(-2147483648)`,
right: `Some(2147483647)`', tests/cast.rs:241:5
stack backtrace:
0: rust_begin_unwind
at /usr/src/rustc-1.59.0/library/std/src/panicking.rs:498:5
1: core::panicking::panic_fmt
at /usr/src/rustc-1.59.0/library/core/src/panicking.rs:116:14
2: core::panicking::assert_failed_inner
at /usr/src/rustc-1.59.0/library/core/src/panicking.rs:197:17
3: core::panicking::assert_failed
at /usr/src/rustc-1.59.0/library/core/src/panicking.rs:154:5
4: cast::cast_float_to_int_edge_cases
at /usr/share/cargo/registry/num-traits-0.2.15/tests/cast.rs:241:5
5: cast::cast_float_to_int_edge_cases::{{closure}}
at /usr/share/cargo/registry/num-traits-0.2.15/tests/cast.rs:238:1
6: core::ops::function::FnOnce::call_once
at /usr/src/rustc-1.59.0/library/core/src/ops/function.rs:227:5
7: core::ops::function::FnOnce::call_once
at /usr/src/rustc-1.59.0/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Can be found on: https://buildd.debian.org/status/package.php?p=rust-num-traits&suite=sid
Different from: https://github.com/rust-num/num-traits/issues/151
I don't remember why I put that "{.0}" precision limit in the format string, but unrestricted it looks like this on i686:
testing cast edge cases for f64 -> isize
testing min -2147483648
vs. -2147483648.9999995
and -2147483649
The expectation is that the first "vs." should truncate and cast to Some(isize::MIN), but it looks like your system wrapped around to isize::MAX. The second value is still too large after truncating, so it should cast None, but you didn't get that far.
I'm guessing this is a compiler codegen issue for mips, either in rustc or llvm, but I don't have the means to test mips myself. There's nothing arch-specific about this code though, and it works on other 32-bit targets.
Within Debian, I have access to mips machine. I can do some testing for you if you want :)
I got it working under qemu, although I used static musl, but I don't think libc matters here. It works fine for me on both mips and mipsel, using both rustup stable and 1.59 (like your debian rustc). Can you try on your system with upstream rustc?
Here's an extracted test program you can try as well:
#[cfg(not(target_pointer_width = "32"))]
compile_error!("this test is 32-bit only");
const MIN_M1: f64 = isize::MIN as f64 - 1.0;
const MAX_P1: f64 = isize::MAX as f64 + 1.0;
fn cast(x: f64) -> Option<isize> {
if x > MIN_M1 && x < MAX_P1 {
Some(unsafe { x.to_int_unchecked() })
} else {
None
}
}
fn main() {
dbg!(MIN_M1, MAX_P1);
for (x, expected) in [
(-2147483649.0, None),
(-2147483648.9999995, Some(isize::MIN)),
(2147483647.9999998, Some(isize::MAX)),
(2147483648.0, None),
] {
let i = cast(x);
dbg!(x, i);
assert_eq!(i, expected);
}
}