about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/mir/interpret/value.rs19
-rw-r--r--src/librustc_mir/hair/constant.rs11
-rw-r--r--src/librustc_mir/interpret/cast.rs42
-rw-r--r--src/librustc_mir/interpret/operator.rs20
4 files changed, 41 insertions, 51 deletions
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 454a4e2111a..1909f3cb998 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -1,5 +1,6 @@
 use std::fmt;
 use rustc_macros::HashStable;
+use rustc_apfloat::{Float, ieee::{Double, Single}};
 
 use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}, subst::SubstsRef};
 use crate::ty::PlaceholderConst;
@@ -292,12 +293,12 @@ impl<'tcx, Tag> Scalar<Tag> {
     }
 
     #[inline]
-    pub fn from_f32(f: f32) -> Self {
+    pub fn from_f32(f: Single) -> Self {
         Scalar::Raw { data: f.to_bits() as u128, size: 4 }
     }
 
     #[inline]
-    pub fn from_f64(f: f64) -> Self {
+    pub fn from_f64(f: Double) -> Self {
         Scalar::Raw { data: f.to_bits() as u128, size: 8 }
     }
 
@@ -427,13 +428,15 @@ impl<'tcx, Tag> Scalar<Tag> {
     }
 
     #[inline]
-    pub fn to_f32(self) -> InterpResult<'static, f32> {
-        Ok(f32::from_bits(self.to_u32()?))
+    pub fn to_f32(self) -> InterpResult<'static, Single> {
+        // Going through `u32` to check size and truncation.
+        Ok(Single::from_bits(self.to_u32()? as u128))
     }
 
     #[inline]
-    pub fn to_f64(self) -> InterpResult<'static, f64> {
-        Ok(f64::from_bits(self.to_u64()?))
+    pub fn to_f64(self) -> InterpResult<'static, Double> {
+        // Going through `u64` to check size and truncation.
+        Ok(Double::from_bits(self.to_u64()? as u128))
     }
 }
 
@@ -517,12 +520,12 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
     }
 
     #[inline(always)]
-    pub fn to_f32(self) -> InterpResult<'tcx, f32> {
+    pub fn to_f32(self) -> InterpResult<'tcx, Single> {
         self.not_undef()?.to_f32()
     }
 
     #[inline(always)]
-    pub fn to_f64(self) -> InterpResult<'tcx, f64> {
+    pub fn to_f64(self) -> InterpResult<'tcx, Double> {
         self.not_undef()?.to_f64()
     }
 
diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs
index b5604f4cb0f..37a2e79dae9 100644
--- a/src/librustc_mir/hair/constant.rs
+++ b/src/librustc_mir/hair/constant.rs
@@ -69,8 +69,7 @@ fn parse_float<'tcx>(
 ) -> Result<ConstValue<'tcx>, ()> {
     let num = num.as_str();
     use rustc_apfloat::ieee::{Single, Double};
-    use rustc_apfloat::Float;
-    let (data, size) = match fty {
+    let scalar = match fty {
         ast::FloatTy::F32 => {
             num.parse::<f32>().map_err(|_| ())?;
             let mut f = num.parse::<Single>().unwrap_or_else(|e| {
@@ -79,19 +78,19 @@ fn parse_float<'tcx>(
             if neg {
                 f = -f;
             }
-            (f.to_bits(), 4)
+            Scalar::from_f32(f)
         }
         ast::FloatTy::F64 => {
             num.parse::<f64>().map_err(|_| ())?;
             let mut f = num.parse::<Double>().unwrap_or_else(|e| {
-                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+                panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
             });
             if neg {
                 f = -f;
             }
-            (f.to_bits(), 8)
+            Scalar::from_f64(f)
         }
     };
 
-    Ok(ConstValue::Scalar(Scalar::from_uint(data, Size::from_bytes(size))))
+    Ok(ConstValue::Scalar(scalar))
 }
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 5bc8b931ae8..4395f0c947b 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -166,21 +166,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
                 Ok(Scalar::from_uint(v, dest_layout.size))
             }
 
-            Float(FloatTy::F32) if signed => Ok(Scalar::from_uint(
-                Single::from_i128(v as i128).value.to_bits(),
-                Size::from_bits(32)
+            Float(FloatTy::F32) if signed => Ok(Scalar::from_f32(
+                Single::from_i128(v as i128).value
             )),
-            Float(FloatTy::F64) if signed => Ok(Scalar::from_uint(
-                Double::from_i128(v as i128).value.to_bits(),
-                Size::from_bits(64)
+            Float(FloatTy::F64) if signed => Ok(Scalar::from_f64(
+                Double::from_i128(v as i128).value
             )),
-            Float(FloatTy::F32) => Ok(Scalar::from_uint(
-                Single::from_u128(v).value.to_bits(),
-                Size::from_bits(32)
+            Float(FloatTy::F32) => Ok(Scalar::from_f32(
+                Single::from_u128(v).value
             )),
-            Float(FloatTy::F64) => Ok(Scalar::from_uint(
-                Double::from_u128(v).value.to_bits(),
-                Size::from_bits(64)
+            Float(FloatTy::F64) => Ok(Scalar::from_f64(
+                Double::from_u128(v).value
             )),
 
             Char => {
@@ -223,22 +219,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
                 Ok(Scalar::from_int(v, Size::from_bits(width as u64)))
             },
             // f64 -> f32
-            Float(FloatTy::F32) if fty == FloatTy::F64 => {
-                Ok(Scalar::from_uint(
-                    Single::to_bits(Double::from_bits(bits).convert(&mut false).value),
-                    Size::from_bits(32),
-                ))
-            },
+            Float(FloatTy::F32) if fty == FloatTy::F64 =>
+                Ok(Scalar::from_f32(Double::from_bits(bits).convert(&mut false).value)),
             // f32 -> f64
-            Float(FloatTy::F64) if fty == FloatTy::F32 => {
-                Ok(Scalar::from_uint(
-                    Double::to_bits(Single::from_bits(bits).convert(&mut false).value),
-                    Size::from_bits(64),
-                ))
-            },
+            Float(FloatTy::F64) if fty == FloatTy::F32 =>
+                Ok(Scalar::from_f64(Single::from_bits(bits).convert(&mut false).value)),
             // identity cast
-            Float(FloatTy:: F64) => Ok(Scalar::from_uint(bits, Size::from_bits(64))),
-            Float(FloatTy:: F32) => Ok(Scalar::from_uint(bits, Size::from_bits(32))),
+            Float(FloatTy::F64) if fty == FloatTy::F64 =>
+                Ok(Scalar::from_uint(bits, Size::from_bits(64))),
+            Float(FloatTy::F32) if fty == FloatTy::F32 =>
+                Ok(Scalar::from_uint(bits, Size::from_bits(32))),
             _ => err!(Unimplemented(format!("float to {:?} cast", dest_ty))),
         }
     }
diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs
index 4f13eeb6fa4..fa4597c825a 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/src/librustc_mir/interpret/operator.rs
@@ -1,5 +1,5 @@
 use rustc::mir;
-use rustc::ty::{self, layout::{Size, TyLayout}};
+use rustc::ty::{self, layout::TyLayout};
 use syntax::ast::FloatTy;
 use rustc_apfloat::ieee::{Double, Single};
 use rustc_apfloat::Float;
@@ -92,11 +92,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
         use rustc::mir::BinOp::*;
 
         macro_rules! float_math {
-            ($ty:path, $size:expr) => {{
+            ($ty:path, $from_float:ident) => {{
                 let l = <$ty>::from_bits(l);
                 let r = <$ty>::from_bits(r);
-                let bitify = |res: ::rustc_apfloat::StatusAnd<$ty>|
-                    Scalar::from_uint(res.value.to_bits(), Size::from_bytes($size));
                 let val = match bin_op {
                     Eq => Scalar::from_bool(l == r),
                     Ne => Scalar::from_bool(l != r),
@@ -104,19 +102,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
                     Le => Scalar::from_bool(l <= r),
                     Gt => Scalar::from_bool(l > r),
                     Ge => Scalar::from_bool(l >= r),
-                    Add => bitify(l + r),
-                    Sub => bitify(l - r),
-                    Mul => bitify(l * r),
-                    Div => bitify(l / r),
-                    Rem => bitify(l % r),
+                    Add => Scalar::$from_float((l + r).value),
+                    Sub => Scalar::$from_float((l - r).value),
+                    Mul => Scalar::$from_float((l * r).value),
+                    Div => Scalar::$from_float((l / r).value),
+                    Rem => Scalar::$from_float((l % r).value),
                     _ => bug!("invalid float op: `{:?}`", bin_op),
                 };
                 return Ok((val, false));
             }};
         }
         match fty {
-            FloatTy::F32 => float_math!(Single, 4),
-            FloatTy::F64 => float_math!(Double, 8),
+            FloatTy::F32 => float_math!(Single, from_f32),
+            FloatTy::F64 => float_math!(Double, from_f64),
         }
     }