about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2018-11-28 17:15:40 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2018-11-28 17:15:40 +0100
commitafb8cba5fc611a652a674b44f1bbf26d200e1aa9 (patch)
treeff3df6be838453307f553cc56f29f4150be75644
parent40412dc09a0fc4a4d2a38709614755b7b4be23da (diff)
downloadrust-afb8cba5fc611a652a674b44f1bbf26d200e1aa9.tar.gz
rust-afb8cba5fc611a652a674b44f1bbf26d200e1aa9.zip
Move hir::Lit -> ty::Const conversion into its own file
-rw-r--r--src/librustc_mir/hair/constant.rs102
-rw-r--r--src/librustc_mir/hair/cx/mod.rs2
-rw-r--r--src/librustc_mir/hair/mod.rs1
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs102
4 files changed, 106 insertions, 101 deletions
diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs
new file mode 100644
index 00000000000..c98ef31c2ba
--- /dev/null
+++ b/src/librustc_mir/hair/constant.rs
@@ -0,0 +1,102 @@
+use syntax::ast;
+use rustc::ty::{self, Ty, TyCtxt, ParamEnv};
+use syntax_pos::symbol::Symbol;
+use rustc::mir::interpret::{ConstValue, Scalar};
+
+#[derive(PartialEq)]
+crate enum LitToConstError {
+    UnparseableFloat,
+    Reported,
+}
+
+crate fn lit_to_const<'a, 'gcx, 'tcx>(
+    lit: &'tcx ast::LitKind,
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    ty: Ty<'tcx>,
+    neg: bool,
+) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
+    use syntax::ast::*;
+
+    let trunc = |n| {
+        let param_ty = ParamEnv::reveal_all().and(tcx.lift_to_global(&ty).unwrap());
+        let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
+        trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
+        let shift = 128 - width.bits();
+        let result = (n << shift) >> shift;
+        trace!("trunc result: {}", result);
+        Ok(ConstValue::Scalar(Scalar::Bits {
+            bits: result,
+            size: width.bytes() as u8,
+        }))
+    };
+
+    use rustc::mir::interpret::*;
+    let lit = match *lit {
+        LitKind::Str(ref s, _) => {
+            let s = s.as_str();
+            let id = tcx.allocate_bytes(s.as_bytes());
+            ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
+        },
+        LitKind::ByteStr(ref data) => {
+            let id = tcx.allocate_bytes(data);
+            ConstValue::Scalar(Scalar::Ptr(id.into()))
+        },
+        LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
+            bits: n as u128,
+            size: 1,
+        }),
+        LitKind::Int(n, _) if neg => {
+            let n = n as i128;
+            let n = n.overflowing_neg().0;
+            trunc(n as u128)?
+        },
+        LitKind::Int(n, _) => trunc(n)?,
+        LitKind::Float(n, fty) => {
+            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
+        }
+        LitKind::FloatUnsuffixed(n) => {
+            let fty = match ty.sty {
+                ty::Float(fty) => fty,
+                _ => bug!()
+            };
+            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
+        }
+        LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
+        LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
+    };
+    Ok(ty::Const::from_const_value(tcx, lit, ty))
+}
+
+fn parse_float<'tcx>(
+    num: Symbol,
+    fty: ast::FloatTy,
+    neg: bool,
+) -> Result<ConstValue<'tcx>, ()> {
+    let num = num.as_str();
+    use rustc_apfloat::ieee::{Single, Double};
+    use rustc_apfloat::Float;
+    let (bits, size) = match fty {
+        ast::FloatTy::F32 => {
+            num.parse::<f32>().map_err(|_| ())?;
+            let mut f = num.parse::<Single>().unwrap_or_else(|e| {
+                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+            });
+            if neg {
+                f = -f;
+            }
+            (f.to_bits(), 4)
+        }
+        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)
+            });
+            if neg {
+                f = -f;
+            }
+            (f.to_bits(), 8)
+        }
+    };
+
+    Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
+}
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index ea1ec24c991..c414088b653 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -31,7 +31,7 @@ use syntax::attr;
 use syntax::symbol::Symbol;
 use rustc::hir;
 use rustc_data_structures::sync::Lrc;
-use hair::pattern::{lit_to_const, LitToConstError};
+use hair::constant::{lit_to_const, LitToConstError};
 
 #[derive(Clone)]
 pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index 3078f10598c..e604b118eac 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -26,6 +26,7 @@ use syntax_pos::Span;
 use self::cx::Cx;
 
 pub mod cx;
+mod constant;
 
 pub mod pattern;
 pub use self::pattern::{BindingMode, Pattern, PatternKind, FieldPattern};
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index deea03acf0c..61d8297fec9 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -19,11 +19,12 @@ pub(crate) use self::check_match::check_match;
 use const_eval::{const_field, const_variant_index};
 
 use hair::util::UserAnnotatedTyHelpers;
+use hair::constant::*;
 
 use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
 use rustc::mir::{ProjectionElem, UserTypeAnnotation, UserTypeProjection, UserTypeProjections};
 use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
-use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, ParamEnv};
+use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
 use rustc::ty::subst::{Substs, Kind};
 use rustc::ty::layout::VariantIdx;
 use rustc::hir::{self, PatKind, RangeEnd};
@@ -37,7 +38,6 @@ use std::fmt;
 use syntax::ast;
 use syntax::ptr::P;
 use syntax_pos::Span;
-use syntax_pos::symbol::Symbol;
 
 #[derive(Clone, Debug)]
 pub enum PatternError {
@@ -1292,101 +1292,3 @@ pub fn compare_const_vals<'a, 'tcx>(
 
     fallback()
 }
-
-#[derive(PartialEq)]
-pub enum LitToConstError {
-    UnparseableFloat,
-    Reported,
-}
-
-pub fn lit_to_const<'a, 'gcx, 'tcx>(
-    lit: &'tcx ast::LitKind,
-    tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    ty: Ty<'tcx>,
-    neg: bool,
-) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
-    use syntax::ast::*;
-
-    let trunc = |n| {
-        let param_ty = ParamEnv::reveal_all().and(tcx.lift_to_global(&ty).unwrap());
-        let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
-        trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
-        let shift = 128 - width.bits();
-        let result = (n << shift) >> shift;
-        trace!("trunc result: {}", result);
-        Ok(ConstValue::Scalar(Scalar::Bits {
-            bits: result,
-            size: width.bytes() as u8,
-        }))
-    };
-
-    use rustc::mir::interpret::*;
-    let lit = match *lit {
-        LitKind::Str(ref s, _) => {
-            let s = s.as_str();
-            let id = tcx.allocate_bytes(s.as_bytes());
-            ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
-        },
-        LitKind::ByteStr(ref data) => {
-            let id = tcx.allocate_bytes(data);
-            ConstValue::Scalar(Scalar::Ptr(id.into()))
-        },
-        LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
-            bits: n as u128,
-            size: 1,
-        }),
-        LitKind::Int(n, _) if neg => {
-            let n = n as i128;
-            let n = n.overflowing_neg().0;
-            trunc(n as u128)?
-        },
-        LitKind::Int(n, _) => trunc(n)?,
-        LitKind::Float(n, fty) => {
-            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
-        }
-        LitKind::FloatUnsuffixed(n) => {
-            let fty = match ty.sty {
-                ty::Float(fty) => fty,
-                _ => bug!()
-            };
-            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
-        }
-        LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
-        LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
-    };
-    Ok(ty::Const::from_const_value(tcx, lit, ty))
-}
-
-pub fn parse_float<'tcx>(
-    num: Symbol,
-    fty: ast::FloatTy,
-    neg: bool,
-) -> Result<ConstValue<'tcx>, ()> {
-    let num = num.as_str();
-    use rustc_apfloat::ieee::{Single, Double};
-    use rustc_apfloat::Float;
-    let (bits, size) = match fty {
-        ast::FloatTy::F32 => {
-            num.parse::<f32>().map_err(|_| ())?;
-            let mut f = num.parse::<Single>().unwrap_or_else(|e| {
-                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
-            });
-            if neg {
-                f = -f;
-            }
-            (f.to_bits(), 4)
-        }
-        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)
-            });
-            if neg {
-                f = -f;
-            }
-            (f.to_bits(), 8)
-        }
-    };
-
-    Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
-}