From afb8cba5fc611a652a674b44f1bbf26d200e1aa9 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 28 Nov 2018 17:15:40 +0100 Subject: [PATCH] Move hir::Lit -> ty::Const conversion into its own file --- src/librustc_mir/hair/constant.rs | 102 +++++++++++++++++++++++++++ src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/hair/mod.rs | 1 + src/librustc_mir/hair/pattern/mod.rs | 102 +-------------------------- 4 files changed, 106 insertions(+), 101 deletions(-) create mode 100644 src/librustc_mir/hair/constant.rs 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, ()> { + 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::().map_err(|_| ())?; + let mut f = num.parse::().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::().map_err(|_| ())?; + let mut f = num.parse::().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::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 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 @@ 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 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, ()> { - 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::().map_err(|_| ())?; - let mut f = num.parse::().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::().map_err(|_| ())?; - let mut f = num.parse::().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 })) -} -- 2.44.0