-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NaN > NaN returns true #50811
Comments
Playground link for this test. https://play.rust-lang.org/?gist=4d6f7f54553b065615caac65b3cb6222&version=nightly&mode=debug Affects both debug and release, Nightly and Stable. |
fn main() {
let operator = std::f64::NAN > std::f64::NAN;
let method = std::f64::NAN.gt(&std::f64::NAN);
println!("{} {}", operator, method); // false false
assert_eq!(operator, method); // doesn't fail
assert_eq!(std::f64::NAN > std::f64::NAN, std::f64::NAN.gt(&std::f64::NAN)); // fails
}
|
This seems to be a regression introduced by 1.26. |
Reduced, extern { fn abort() -> !; }
fn main() {
let f = &(std::f64::NAN > std::f64::NAN);
if *f {
unsafe { abort(); }
}
} Edit: Or maybe a bug in Miri (cc @oli-obk) extern { fn abort() -> !; }
static B: bool = std::f64::NAN > std::f64::NAN;
fn main() {
if B {
unsafe { abort(); }
}
} |
Bisection between c83fa5d...097efa9 gives #46882 as the regression PR, as expected. |
I guess this logic, which I blindly copied, was never correct to begin with: https://github.com/rust-lang/rust/blob/master/src/librustc_mir/interpret/operator.rs#L188 I think this is how old const eval did it, and we didn't want to regress that. cc @eddyb |
40b118c#diff-580fb7d0b0ede57fb2ce24a5dd33910cL50 Has the comment about existing bad behaviour. |
@oli-obk The old logic used unwrap, meaning Edit: 🤔 The unwrap is in 40b118c#diff-e847a6da94440f7bf6783206efe4275bL138 |
The incorrect behavior mentioned in #50811 (comment) was this: let x: [u8; (std::f64::NAN > std::f64::NAN) as usize] = [1]; If we fix the float comparison behavior, this code will no longer compile. But I think this is clearly a bug fix and breaking code like this is acceptable. |
Fixed in #50812 |
…li-obk Fix issue #50811 (`NaN > NaN` was true). Fix #50811 Make sure the float comparison output is consistent with the expected behavior when NaN is involved. ---- Note: This PR is a **BREAKING CHANGE**. If you have used `>` or `>=` to compare floats, and make the result as the length of a fixed array type, like: ```rust use std::f64::NAN; let x: [u8; (NAN > NAN) as usize] = [1]; ``` then the code will no longer compile. Previously, all float comparison involving NaN will just return "Greater", i.e. `NAN > NAN` would wrongly return `true` during const evaluation. If you need to retain the old behavior (why), you may replace `a > b` with `a != a || b != b || a > b`.
Fix rust-lang#50811 Make sure the float comparison output is consistent with the expected behavior when NaN is involved. ---- Note: This PR is a **BREAKING CHANGE**. If you have used `>` or `>=` to compare floats, and make the result as the length of a fixed array type, like: ```rust use std::f64::NAN; let x: [u8; (NAN > NAN) as usize] = [1]; ``` then the code will no longer compile. Previously, all float comparison involving NaN will just return "Greater", i.e. `NAN > NAN` would wrongly return `true` during const evaluation. If you need to retain the old behavior (why), you may replace `a > b` with `a != a || b != b || a > b`.
[beta] Process backports Merged and approved: * #50812: Fix issue #50811 (`NaN > NaN` was true). * #50827: Update LLVM to `56c931901cfb85cd6f7ed44c7d7520a8de1edf97` * #50879: Fix naming conventions for new lints * #51011: rustdoc: hide macro export statements from docs * #51051: prohibit turbofish in `impl Trait` methods * #51052: restore emplacement syntax (obsolete) * #51146: typeck: Do not pass the field check on field error * #51235: remove notion of Implicit derefs from mem-cat r? @ghost
[beta] Process backports Merged and approved: * #50812: Fix issue #50811 (`NaN > NaN` was true). * #50879: Fix naming conventions for new lints * #51011: rustdoc: hide macro export statements from docs * #51051: prohibit turbofish in impl Trait methods * #51052: restore emplacement syntax (obsolete) * #51146: typeck: Do not pass the field check on field error * #51235: remove notion of Implicit derefs from mem-cat r? @ghost
The following tests do not pass for me, but I think they should, as comparisons with NaN should always simply evaluate to
false
:I get this result on both debug and release builds. I'm on an x86_64 running Linux, rustc 1.27.0-nightly (f0fdaba 2018-05-15).
The text was updated successfully, but these errors were encountered: