diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 8614f7bd58e2..63494438f7d8 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1831,6 +1831,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { ) -> Option> { let param_env = ParamEnv::empty(traits::Reveal::UserFacing); let repr_type = self.repr.discr_type(); + let bit_size = layout::Integer::from_attr(tcx, repr_type).size().bits(); let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); let instance = ty::Instance::new(expr_did, substs); let cid = GlobalId { @@ -1844,22 +1845,10 @@ impl<'a, 'gcx, 'tcx> AdtDef { }) => { trace!("discriminants: {} ({:?})", b, repr_type); let ty = repr_type.to_ty(tcx); - if ty.is_signed() { - let (ty, param_env) = tcx - .lift_to_global(&(ty, param_env)) - .unwrap_or_else(|| { - bug!("MIR: discriminants({:?}, {:?}) got \ - type with inference types/regions", - ty, param_env); - }); - let size = tcx.global_tcx() - .layout_of(param_env.and(ty)) - .expect("int layout") - .size - .bits(); + if repr_type.is_signed() { let val = b as i128; // sign extend to i128 - let amt = 128 - size; + let amt = 128 - bit_size; let val = (val << amt) >> amt; Some(Discr { val: val as u128, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index ec484785ca2f..28eef70679b9 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -151,22 +151,13 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { pub fn type_bit_size( &self, - ty: Ty<'tcx>, + ty: Ty, ) -> u64 { - let tcx = self.tcx.global_tcx(); - let (ty, param_env) = self - .tcx - .lift_to_global(&(ty, self.param_env)) - .unwrap_or_else(|| { - bug!("MIR: Cx::const_eval_literal({:?}, {:?}) got \ - type with inference types/regions", - ty, self.param_env); - }); - tcx - .layout_of(param_env.and(ty)) - .expect("int layout") - .size - .bits() + match ty.sty { + ty::TyInt(ity) => ity.bit_width(), + ty::TyUint(uty) => uty.bit_width(), + _ => bug!("{} is not an integer", ty), + }.map_or(self.tcx.data_layout.pointer_size.bits(), |n| n as u64) } pub fn const_eval_literal( diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 97056dd66bbb..13090ca53302 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1256,7 +1256,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M pointee_ty: Ty<'tcx>, ) -> EvalResult<'tcx, Value> { let ptr_size = self.memory.pointer_size(); - let p: Pointer = self.memory.read_ptr_sized_unsigned(ptr, ptr_align)?.into(); + let p: Pointer = self.memory.read_ptr_sized(ptr, ptr_align)?.into(); if self.type_is_sized(pointee_ty) { Ok(p.to_value()) } else { @@ -1264,12 +1264,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let extra = ptr.offset(ptr_size, self)?; match self.tcx.struct_tail(pointee_ty).sty { ty::TyDynamic(..) => Ok(p.to_value_with_vtable( - self.memory.read_ptr_sized_unsigned(extra, ptr_align)?.to_ptr()?, + self.memory.read_ptr_sized(extra, ptr_align)?.to_ptr()?, )), ty::TySlice(..) | ty::TyStr => { let len = self .memory - .read_ptr_sized_unsigned(extra, ptr_align)? + .read_ptr_sized(extra, ptr_align)? .to_bytes()?; Ok(p.to_value_with_len(len as u64)) }, @@ -1284,7 +1284,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let ptr = ptr.to_ptr()?; let val = match ty.sty { ty::TyBool => { - let val = self.memory.read_primval(ptr, ptr_align, 1, false)?; + let val = self.memory.read_primval(ptr, ptr_align, 1)?; let val = match val { PrimVal::Bytes(0) => false, PrimVal::Bytes(1) => true, @@ -1294,7 +1294,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M PrimVal::from_bool(val) } ty::TyChar => { - let c = self.memory.read_primval(ptr, ptr_align, 4, false)?.to_bytes()? as u32; + let c = self.memory.read_primval(ptr, ptr_align, 4)?.to_bytes()? as u32; match ::std::char::from_u32(c) { Some(ch) => PrimVal::from_char(ch), None => return err!(InvalidChar(c as u128)), @@ -1311,7 +1311,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M I128 => 16, Isize => self.memory.pointer_size(), }; - self.memory.read_primval(ptr, ptr_align, size, true)? + self.memory.read_primval(ptr, ptr_align, size)? } ty::TyUint(uint_ty) => { @@ -1324,17 +1324,17 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M U128 => 16, Usize => self.memory.pointer_size(), }; - self.memory.read_primval(ptr, ptr_align, size, false)? + self.memory.read_primval(ptr, ptr_align, size)? } ty::TyFloat(FloatTy::F32) => { - PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 4, false)?.to_bytes()?) + PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 4)?.to_bytes()?) } ty::TyFloat(FloatTy::F64) => { - PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 8, false)?.to_bytes()?) + PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 8)?.to_bytes()?) } - ty::TyFnPtr(_) => self.memory.read_ptr_sized_unsigned(ptr, ptr_align)?, + ty::TyFnPtr(_) => self.memory.read_ptr_sized(ptr, ptr_align)?, ty::TyRef(_, ref tam) | ty::TyRawPtr(ref tam) => return self.read_ptr(ptr, ptr_align, tam.ty).map(Some), @@ -1344,12 +1344,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M } if let layout::Abi::Scalar(ref scalar) = self.layout_of(ty)?.abi { - let mut signed = false; - if let layout::Int(_, s) = scalar.value { - signed = s; - } let size = scalar.value.size(self).bytes(); - self.memory.read_primval(ptr, ptr_align, size, signed)? + self.memory.read_primval(ptr, ptr_align, size)? } else { return Ok(None); } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 4e5bf25ca3b4..b369f80e849b 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -655,7 +655,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { Ok(()) } - pub fn read_primval(&self, ptr: MemoryPointer, ptr_align: Align, size: u64, signed: bool) -> EvalResult<'tcx, PrimVal> { + pub fn read_primval(&self, ptr: MemoryPointer, ptr_align: Align, size: u64) -> EvalResult<'tcx, PrimVal> { self.check_relocation_edges(ptr, size)?; // Make sure we don't read part of a pointer as a pointer let endianness = self.endianness(); let bytes = self.get_bytes_unchecked(ptr, size, ptr_align.min(self.int_align(size)))?; @@ -665,14 +665,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { return Ok(PrimVal::Undef.into()); } // Now we do the actual reading - let bytes = if signed { - let bytes = read_target_int(endianness, bytes).unwrap() as u128; - let amt = 128 - (size * 8); - // truncate (shift left to drop out leftover values, shift right to fill with zeroes) - (bytes << amt) >> amt - } else { - read_target_uint(endianness, bytes).unwrap() - }; + let bytes = read_target_uint(endianness, bytes).unwrap(); // See if we got a pointer if size != self.pointer_size() { if self.relocations(ptr, size)?.count() != 0 { @@ -689,8 +682,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { Ok(PrimVal::Bytes(bytes)) } - pub fn read_ptr_sized_unsigned(&self, ptr: MemoryPointer, ptr_align: Align) -> EvalResult<'tcx, PrimVal> { - self.read_primval(ptr, ptr_align, self.pointer_size(), false) + pub fn read_ptr_sized(&self, ptr: MemoryPointer, ptr_align: Align) -> EvalResult<'tcx, PrimVal> { + self.read_primval(ptr, ptr_align, self.pointer_size()) } pub fn write_primval(&mut self, ptr: MemoryPointer, ptr_align: Align, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> { @@ -901,13 +894,6 @@ pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result } } -pub fn read_target_int(endianness: layout::Endian, mut source: &[u8]) -> Result { - match endianness { - layout::Endian::Little => source.read_int128::(source.len()), - layout::Endian::Big => source.read_int128::(source.len()), - } -} - //////////////////////////////////////////////////////////////////////////////// // Unaligned accesses //////////////////////////////////////////////////////////////////////////////// @@ -924,7 +910,7 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> { ) -> EvalResult<'tcx, Pointer> { Ok(match value { Value::ByRef(ptr, align) => { - self.memory().read_ptr_sized_unsigned(ptr.to_ptr()?, align)? + self.memory().read_ptr_sized(ptr.to_ptr()?, align)? } Value::ByVal(ptr) | Value::ByValPair(ptr, _) => ptr, @@ -938,8 +924,8 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> { match value { Value::ByRef(ref_ptr, align) => { let mem = self.memory(); - let ptr = mem.read_ptr_sized_unsigned(ref_ptr.to_ptr()?, align)?.into(); - let vtable = mem.read_ptr_sized_unsigned( + let ptr = mem.read_ptr_sized(ref_ptr.to_ptr()?, align)?.into(); + let vtable = mem.read_ptr_sized( ref_ptr.offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?, align )?.to_ptr()?; @@ -960,8 +946,8 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> { match value { Value::ByRef(ref_ptr, align) => { let mem = self.memory(); - let ptr = mem.read_ptr_sized_unsigned(ref_ptr.to_ptr()?, align)?.into(); - let len = mem.read_ptr_sized_unsigned( + let ptr = mem.read_ptr_sized(ref_ptr.to_ptr()?, align)?.into(); + let len = mem.read_ptr_sized( ref_ptr.offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?, align )?.to_bytes()? as u64; diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index b1ee3d568fd1..ae6337d82c3e 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -30,4 +30,4 @@ pub use self::const_eval::{ pub use self::machine::Machine; -pub use self::memory::{write_target_uint, write_target_int, read_target_uint, read_target_int}; +pub use self::memory::{write_target_uint, write_target_int, read_target_uint}; diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index 51dee0aaff47..babc78470147 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -401,7 +401,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { let ptr_size = self.memory.pointer_size(); let ptr_align = self.tcx.data_layout.pointer_align; let (ptr, vtable) = self.into_ptr_vtable_pair(args[0].value)?; - let fn_ptr = self.memory.read_ptr_sized_unsigned( + let fn_ptr = self.memory.read_ptr_sized( vtable.offset(ptr_size * (idx as u64 + 3), &self)?, ptr_align )?.to_ptr()?; diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index c67cf1c84bf0..ded27108e716 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -79,8 +79,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { ) -> EvalResult<'tcx, (Size, Align)> { let pointer_size = self.memory.pointer_size(); let pointer_align = self.tcx.data_layout.pointer_align; - let size = self.memory.read_ptr_sized_unsigned(vtable.offset(pointer_size, self)?, pointer_align)?.to_bytes()? as u64; - let align = self.memory.read_ptr_sized_unsigned( + let size = self.memory.read_ptr_sized(vtable.offset(pointer_size, self)?, pointer_align)?.to_bytes()? as u64; + let align = self.memory.read_ptr_sized( vtable.offset(pointer_size * 2, self)?, pointer_align )?.to_bytes()? as u64;