about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2018-05-24 17:50:47 -0600
committerMark Simulacrum <mark.simulacrum@gmail.com>2018-05-25 09:42:42 -0600
commitd37c75d3c38b013ca9bd747d45e9e2f752cedb05 (patch)
tree6227c142fbae4e12b4f51b75978d3d4fd44ef9e7
parent6dc26666121ae7bc1560e806f0bc60baf68242fe (diff)
downloadrust-d37c75d3c38b013ca9bd747d45e9e2f752cedb05.tar.gz
rust-d37c75d3c38b013ca9bd747d45e9e2f752cedb05.zip
Fix 07c42af554c to work on stable
-rw-r--r--src/librustc_const_math/float.rs7
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs7
-rw-r--r--src/librustc_mir/interpret/operator.rs25
3 files changed, 28 insertions, 11 deletions
diff --git a/src/librustc_const_math/float.rs b/src/librustc_const_math/float.rs
index 9d820ea8cbe..3030ff80780 100644
--- a/src/librustc_const_math/float.rs
+++ b/src/librustc_const_math/float.rs
@@ -38,19 +38,18 @@ impl ConstFloat {
     }
 
     /// Compares the values if they are of the same type
-    pub fn try_cmp(self, rhs: Self) -> Result<Ordering, ConstMathErr> {
+    pub fn try_cmp(self, rhs: Self) -> Result<Option<Ordering>, ConstMathErr> {
         match (self.ty, rhs.ty) {
             (ast::FloatTy::F64, ast::FloatTy::F64)  => {
                 let a = Double::from_bits(self.bits);
                 let b = Double::from_bits(rhs.bits);
-                // This is pretty bad but it is the existing behavior.
-                Ok(a.partial_cmp(&b).unwrap_or(Ordering::Greater))
+                Ok(a.partial_cmp(&b))
             }
 
             (ast::FloatTy::F32, ast::FloatTy::F32) => {
                 let a = Single::from_bits(self.bits);
                 let b = Single::from_bits(rhs.bits);
-                Ok(a.partial_cmp(&b).unwrap_or(Ordering::Greater))
+                Ok(a.partial_cmp(&b))
             }
 
             _ => Err(CmpBetweenUnequalTypes),
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 02aca73c553..6efef07ebbd 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -1115,7 +1115,12 @@ pub fn compare_const_vals<'a, 'tcx>(
                         ty,
                     };
                     // FIXME(oli-obk): report cmp errors?
-                    l.try_cmp(r).ok()
+                    // FIXME: Just returning Ordering::Greater here is the previous behavior but may
+                    // not be what we want. It means that NaN > NaN is true, which if false.
+                    match l.try_cmp(r) {
+                        Ok(opt) => Some(opt.unwrap_or(Ordering::Greater)),
+                        _ => None,
+                    }
                 },
                 ty::TyInt(_) => {
                     let a = interpret::sign_extend(tcx, a, ty).expect("layout error for TyInt");
diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs
index 727832ec4f4..e6e1ff5a53e 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/src/librustc_mir/interpret/operator.rs
@@ -1,3 +1,5 @@
+use std::cmp::Ordering;
+
 use rustc::mir;
 use rustc::ty::{self, Ty};
 use rustc_const_math::ConstFloat;
@@ -133,13 +135,24 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                 bits: r,
                 ty,
             };
+            let cmp = |l: ConstFloat, r: ConstFloat| -> Option<Ordering> {
+                l.try_cmp(r).unwrap_or(None)
+            };
             match op {
-                Eq => PrimVal::from_bool(l == r),
-                Ne => PrimVal::from_bool(l != r),
-                Lt => PrimVal::from_bool(l < r),
-                Le => PrimVal::from_bool(l <= r),
-                Gt => PrimVal::from_bool(l > r),
-                Ge => PrimVal::from_bool(l >= r),
+                Eq => PrimVal::from_bool(cmp(l, r) == Some(Ordering::Equal)),
+                Ne => PrimVal::from_bool(cmp(l, r) != Some(Ordering::Equal)),
+                Lt => PrimVal::from_bool(cmp(l, r) == Some(Ordering::Less)),
+                Gt => PrimVal::from_bool(cmp(l, r) == Some(Ordering::Greater)),
+                Le => PrimVal::from_bool(match cmp(l, r) {
+                    Some(Ordering::Less) => true,
+                    Some(Ordering::Equal) => true,
+                    _ => false,
+                }),
+                Ge => PrimVal::from_bool(match cmp(l, r) {
+                    Some(Ordering::Greater) => true,
+                    Some(Ordering::Equal) => true,
+                    _ => false,
+                }),
                 Add => PrimVal::Bytes((l + r).unwrap().bits),
                 Sub => PrimVal::Bytes((l - r).unwrap().bits),
                 Mul => PrimVal::Bytes((l * r).unwrap().bits),