Merge pull request #335 from solson/rustup

Rustup
This commit is contained in:
Ralf Jung 2017-09-13 14:36:52 +02:00 committed by GitHub
commit 02a943b3fb
6 changed files with 56 additions and 50 deletions

View file

@ -38,38 +38,45 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
self.cast_from_int(val as u128, ty, val < 0)
}
fn int_to_int(&self, v: i128, ty: IntTy) -> u128 {
match ty {
IntTy::I8 => v as i8 as u128,
IntTy::I16 => v as i16 as u128,
IntTy::I32 => v as i32 as u128,
IntTy::I64 => v as i64 as u128,
IntTy::I128 => v as u128,
IntTy::Is => {
let ty = self.tcx.sess.target.isize_ty;
self.int_to_int(v, ty)
}
}
}
fn int_to_uint(&self, v: u128, ty: UintTy) -> u128 {
match ty {
UintTy::U8 => v as u8 as u128,
UintTy::U16 => v as u16 as u128,
UintTy::U32 => v as u32 as u128,
UintTy::U64 => v as u64 as u128,
UintTy::U128 => v,
UintTy::Us => {
let ty = self.tcx.sess.target.usize_ty;
self.int_to_uint(v, ty)
}
}
}
fn cast_from_int(
&self,
v: u128,
ty: ty::Ty<'tcx>,
negative: bool,
) -> EvalResult<'tcx, PrimVal> {
trace!("cast_from_int: {}, {}, {}", v, ty, negative);
use rustc::ty::TypeVariants::*;
match ty.sty {
// Casts to bool are not permitted by rustc, no need to handle them here.
TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i128 as i8 as u128)),
TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i128 as i16 as u128)),
TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i128 as i32 as u128)),
TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i128 as i64 as u128)),
TyInt(IntTy::I128) => Ok(PrimVal::Bytes(v as u128)),
TyUint(UintTy::U8) => Ok(PrimVal::Bytes(v as u8 as u128)),
TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u128)),
TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u128)),
TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v as u64 as u128)),
TyUint(UintTy::U128) => Ok(PrimVal::Bytes(v)),
TyInt(IntTy::Is) => {
let int_ty = self.tcx.sess.target.int_type;
let ty = self.tcx.mk_mach_int(int_ty);
self.cast_from_int(v, ty, negative)
}
TyUint(UintTy::Us) => {
let uint_ty = self.tcx.sess.target.uint_type;
let ty = self.tcx.mk_mach_uint(uint_ty);
self.cast_from_int(v, ty, negative)
}
TyInt(ty) => Ok(PrimVal::Bytes(self.int_to_int(v as i128, ty))),
TyUint(ty) => Ok(PrimVal::Bytes(self.int_to_uint(v, ty))),
TyFloat(FloatTy::F64) if negative => Ok(PrimVal::from_f64(v as i128 as f64)),
TyFloat(FloatTy::F64) => Ok(PrimVal::from_f64(v as f64)),

View file

@ -92,7 +92,7 @@ pub fn eval_body_as_integer<'a, 'tcx>(
TyInt(IntTy::I64) => ConstInt::I64(prim as i128 as i64),
TyInt(IntTy::I128) => ConstInt::I128(prim as i128),
TyInt(IntTy::Is) => ConstInt::Isize(
ConstIsize::new(prim as i128 as i64, tcx.sess.target.int_type)
ConstIsize::new(prim as i128 as i64, tcx.sess.target.isize_ty)
.expect("miri should already have errored"),
),
TyUint(UintTy::U8) => ConstInt::U8(prim as u8),
@ -101,7 +101,7 @@ pub fn eval_body_as_integer<'a, 'tcx>(
TyUint(UintTy::U64) => ConstInt::U64(prim as u64),
TyUint(UintTy::U128) => ConstInt::U128(prim),
TyUint(UintTy::Us) => ConstInt::Usize(
ConstUsize::new(prim as u64, tcx.sess.target.uint_type)
ConstUsize::new(prim as u64, tcx.sess.target.usize_ty)
.expect("miri should already have errored"),
),
_ => {

View file

@ -240,17 +240,23 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
Str(ref s) => return self.str_to_value(s),
ByteStr(ref bs) => {
let ptr = self.memory.allocate_cached(bs)?;
let ptr = self.memory.allocate_cached(bs.data)?;
PrimVal::Ptr(ptr)
}
Variant(_) => unimplemented!(),
Struct(_) => unimplemented!(),
Tuple(_) => unimplemented!(),
Unevaluated(def_id, substs) => {
let instance = self.resolve_associated_const(def_id, substs);
let cid = GlobalId {
instance,
promoted: None,
};
return Ok(Value::ByRef(*self.globals.get(&cid).expect("static/const not cached")));
}
Aggregate(..) |
Variant(_) => bug!("should not have aggregate or variant constants in MIR"),
// function items are zero sized and thus have no readable value
Function(..) => PrimVal::Undef,
Array(_) => unimplemented!(),
Repeat(_, _) => unimplemented!(),
};
Ok(Value::ByVal(primval))
@ -817,7 +823,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
Repeat(ref operand, _) => {
let (elem_ty, length) = match dest_ty.sty {
ty::TyArray(elem_ty, n) => (elem_ty, n as u64),
ty::TyArray(elem_ty, n) => (elem_ty, n.val.to_const_int().unwrap().to_u64().unwrap()),
_ => {
bug!(
"tried to assign array-repeat to non-array type {:?}",
@ -1288,16 +1294,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
use rustc::mir::Literal;
let mir::Constant { ref literal, .. } = **constant;
let value = match *literal {
Literal::Value { ref value } => self.const_to_value(value)?,
Literal::Item { def_id, substs } => {
let instance = self.resolve_associated_const(def_id, substs);
let cid = GlobalId {
instance,
promoted: None,
};
Value::ByRef(*self.globals.get(&cid).expect("static/const not cached"))
}
Literal::Value { ref value } => self.const_to_value(&value.val)?,
Literal::Promoted { index } => {
let cid = GlobalId {
@ -1920,7 +1917,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
let ptr = src.into_ptr(&self.memory)?;
// u64 cast is from usize to u64, which is always good
let valty = ValTy {
value: ptr.to_value_with_len(length as u64),
value: ptr.to_value_with_len(length.val.to_const_int().unwrap().to_u64().unwrap() ),
ty: dest_ty,
};
self.write_value(valty, dest)
@ -2505,7 +2502,7 @@ struct AssociatedTypeNormalizer<'a, 'tcx: 'a> {
impl<'a, 'tcx> AssociatedTypeNormalizer<'a, 'tcx> {
fn fold<T: TypeFoldable<'tcx>>(&mut self, value: &T) -> T {
if !value.has_projection_types() {
if !value.has_projections() {
value.clone()
} else {
value.fold_with(self)
@ -2519,7 +2516,7 @@ impl<'a, 'tcx> ::rustc::ty::fold::TypeFolder<'tcx, 'tcx> for AssociatedTypeNorma
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if !ty.has_projection_types() {
if !ty.has_projections() {
ty
} else {
self.tcx.normalize_associated_type(&ty)

View file

@ -75,7 +75,7 @@ impl<'tcx> Lvalue {
pub(super) fn elem_ty_and_len(self, ty: Ty<'tcx>) -> (Ty<'tcx>, u64) {
match ty.sty {
ty::TyArray(elem, n) => (elem, n as u64),
ty::TyArray(elem, n) => (elem, n.val.to_const_int().unwrap().to_u64().unwrap() as u64),
ty::TySlice(elem) => {
match self {
@ -266,7 +266,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
let field = field_index as u64;
let elem_size = match base_ty.sty {
ty::TyArray(elem_ty, n) => {
assert!(field < n as u64);
assert!(field < n.val.to_const_int().unwrap().to_u64().unwrap() as u64);
self.type_size(elem_ty)?.expect("array elements are sized") as u64
}
_ => {

View file

@ -10,6 +10,7 @@ use rustc::traits::Reveal;
use rustc::ty;
use rustc::ty::layout::Layout;
use rustc::ty::subst::Substs;
use rustc::middle::const_val::ConstVal;
use super::{EvalResult, EvalContext, StackPopCleanup, PtrAndAlign, GlobalId, Lvalue,
MemoryKind, Machine, PrimVal};
@ -300,8 +301,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
self.super_constant(constant, location);
match constant.literal {
// already computed by rustc
mir::Literal::Value { .. } => {}
mir::Literal::Item { def_id, substs } => {
mir::Literal::Value { value: &ty::Const { val: ConstVal::Unevaluated(def_id, substs), .. } } => {
self.try(|this| {
this.ecx.global_item(
def_id,
@ -311,6 +311,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
)
});
}
mir::Literal::Value { .. } => {}
mir::Literal::Promoted { index } => {
let cid = GlobalId {
instance: self.instance,

View file

@ -246,7 +246,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
{
let param_env = ty::ParamEnv::empty(Reveal::All);
if !value.has_projection_types() {
if !value.has_projections() {
return value.clone();
}
@ -525,6 +525,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
Ok(())
}
TyArray(elem_ty, len) => {
let len = len.val.to_const_int().unwrap().to_u64().unwrap();
for i in 0..len {
let inner_lvalue = self.lvalue_index(query.lval, query.ty, i as u64)?;
self.validate(