From: Ralf Jung Date: Fri, 8 Feb 2019 11:20:55 +0000 (+0100) Subject: make OpTy.op private, and ImmTy.imm public instead X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=e73f96abe7cc3a76223e5d0b50592c287c517750;p=rust.git make OpTy.op private, and ImmTy.imm public instead --- diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index fb0c19f764c..5d6e9d64aeb 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -77,7 +77,7 @@ pub fn op_to_const<'tcx>( let normalized_op = if normalize { ecx.try_read_immediate(op)? } else { - match op.op { + match *op { Operand::Indirect(mplace) => Err(mplace), Operand::Immediate(val) => Ok(val) } @@ -105,15 +105,6 @@ pub fn op_to_const<'tcx>( Ok(ty::Const { val, ty: op.layout.ty }) } -pub fn lazy_const_to_op<'tcx>( - ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, - cnst: ty::LazyConst<'tcx>, - ty: ty::Ty<'tcx>, -) -> EvalResult<'tcx, OpTy<'tcx>> { - let op = ecx.const_value_to_op(cnst)?; - Ok(OpTy { op, layout: ecx.layout_of(ty)? }) -} - fn eval_body_and_ecx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, cid: GlobalId<'tcx>, @@ -486,7 +477,7 @@ pub fn const_field<'a, 'tcx>( let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); let result = (|| { // get the operand again - let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(value), value.ty)?; + let op = ecx.lazy_const_to_op(ty::LazyConst::Evaluated(value), value.ty)?; // downcast let down = match variant { None => op, @@ -512,7 +503,7 @@ pub fn const_variant_index<'a, 'tcx>( ) -> EvalResult<'tcx, VariantIdx> { trace!("const_variant_index: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); - let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(val), val.ty)?; + let op = ecx.lazy_const_to_op(ty::LazyConst::Evaluated(val), val.ty)?; Ok(ecx.read_discriminant(op)?.1) } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index c3b71be8354..ce62d79e585 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -9,7 +9,7 @@ use rustc::mir::CastKind; use rustc_apfloat::Float; -use super::{EvalContext, Machine, PlaceTy, OpTy, Immediate}; +use super::{EvalContext, Machine, PlaceTy, OpTy, ImmTy, Immediate}; impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { @@ -372,7 +372,7 @@ fn unsize_into( assert_eq!(src.layout.fields.offset(i).bytes(), 0); assert_eq!(src_field_layout.size, src.layout.size); // just sawp out the layout - OpTy { op: src.op, layout: src_field_layout } + OpTy::from(ImmTy { imm: src.to_immediate(), layout: src_field_layout }) } }; if src_field.layout.ty == dst_field.layout.ty { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index c0b26442dd9..4d0da5e6ece 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -11,7 +11,10 @@ ConstValue, Pointer, Scalar, EvalResult, EvalErrorKind, }; -use super::{EvalContext, Machine, MemPlace, MPlaceTy, MemoryKind}; +use super::{ + EvalContext, Machine, AllocMap, Allocation, AllocationExtra, + MemPlace, MPlaceTy, PlaceTy, Place, MemoryKind, +}; pub use rustc::mir::interpret::ScalarMaybeUndef; /// A `Value` represents a single immediate self-contained Rust value. @@ -112,7 +115,7 @@ pub fn to_meta(self) -> EvalResult<'tcx, Option>> { // as input for binary and cast operations. #[derive(Copy, Clone, Debug)] pub struct ImmTy<'tcx, Tag=()> { - immediate: Immediate, + crate imm: Immediate, // ideally we'd make this private, but const_prop needs this pub layout: TyLayout<'tcx>, } @@ -120,7 +123,7 @@ impl<'tcx, Tag> ::std::ops::Deref for ImmTy<'tcx, Tag> { type Target = Immediate; #[inline(always)] fn deref(&self) -> &Immediate { - &self.immediate + &self.imm } } @@ -180,7 +183,7 @@ pub fn to_immediate(self) -> Immediate #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct OpTy<'tcx, Tag=()> { - crate op: Operand, // ideally we'd make this private, but const_prop needs this + op: Operand, pub layout: TyLayout<'tcx>, } @@ -206,7 +209,7 @@ impl<'tcx, Tag> From> for OpTy<'tcx, Tag> { #[inline(always)] fn from(val: ImmTy<'tcx, Tag>) -> Self { OpTy { - op: Operand::Immediate(val.immediate), + op: Operand::Immediate(val.imm), layout: val.layout } } @@ -324,8 +327,8 @@ pub fn read_immediate( &self, op: OpTy<'tcx, M::PointerTag> ) -> EvalResult<'tcx, ImmTy<'tcx, M::PointerTag>> { - if let Ok(immediate) = self.try_read_immediate(op)? { - Ok(ImmTy { immediate, layout: op.layout }) + if let Ok(imm) = self.try_read_immediate(op)? { + Ok(ImmTy { imm, layout: op.layout }) } else { bug!("primitive read failed for type: {:?}", op.layout.ty); } @@ -469,6 +472,22 @@ pub fn access_local( Ok(OpTy { op, layout }) } + /// Every place can be read from, so we can turm them into an operand + #[inline(always)] + pub fn place_to_op( + &self, + place: PlaceTy<'tcx, M::PointerTag> + ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { + let op = match *place { + Place::Ptr(mplace) => { + Operand::Indirect(mplace) + } + Place::Local { frame, local } => + *self.stack[frame].locals[local].access()? + }; + Ok(OpTy { op, layout: place.layout }) + } + // Evaluate a place with the goal of reading from it. This lets us sometimes // avoid allocations. fn eval_place_to_op( @@ -531,10 +550,8 @@ pub(super) fn eval_operands( .collect() } - // Used when miri runs into a constant, and by CTFE. - // FIXME: CTFE should use allocations, then we can make this private (embed it into - // `eval_operand`, ideally). - pub(crate) fn const_value_to_op( + // Used when Miri runs into a constant, and (indirectly through lazy_const_to_op) by CTFE. + fn const_value_to_op( &self, val: ty::LazyConst<'tcx>, ) -> EvalResult<'tcx, Operand> { @@ -666,3 +683,21 @@ pub fn read_discriminant( } } + +impl<'a, 'mir, 'tcx, M> EvalContext<'a, 'mir, 'tcx, M> +where + M: Machine<'a, 'mir, 'tcx, PointerTag=()>, + // FIXME: Working around https://github.com/rust-lang/rust/issues/24159 + M::MemoryMap: AllocMap, Allocation<(), M::AllocExtra>)>, + M::AllocExtra: AllocationExtra<(), M::MemoryExtra>, +{ + // FIXME: CTFE should use allocations, then we can remove this. + pub(crate) fn lazy_const_to_op( + &self, + cnst: ty::LazyConst<'tcx>, + ty: ty::Ty<'tcx>, + ) -> EvalResult<'tcx, OpTy<'tcx>> { + let op = self.const_value_to_op(cnst)?; + Ok(OpTy { op, layout: self.layout_of(ty)? }) + } +} diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 004a11e34d6..c1d0f0a8bd1 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -244,10 +244,10 @@ pub(super) fn vtable(self) -> EvalResult<'tcx, Pointer> { } } -impl<'tcx, Tag: ::std::fmt::Debug> OpTy<'tcx, Tag> { +impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { #[inline(always)] pub fn try_as_mplace(self) -> Result, Immediate> { - match self.op { + match *self { Operand::Indirect(mplace) => Ok(MPlaceTy { mplace, layout: self.layout }), Operand::Immediate(imm) => Err(imm), } @@ -487,9 +487,9 @@ pub fn mplace_projection( Deref => self.deref_operand(base.into())?, Index(local) => { - let n = *self.frame().locals[local].access()?; - let n_layout = self.layout_of(self.tcx.types.usize)?; - let n = self.read_scalar(OpTy { op: n, layout: n_layout })?; + let layout = self.layout_of(self.tcx.types.usize)?; + let n = self.access_local(self.frame(), local, Some(layout))?; + let n = self.read_scalar(n)?; let n = n.to_bits(self.tcx.data_layout.pointer_size)?; self.mplace_field(base, u64::try_from(n).unwrap())? } @@ -991,22 +991,6 @@ pub fn write_discriminant_index( Ok(()) } - /// Every place can be read from, so we can turm them into an operand - #[inline(always)] - pub fn place_to_op( - &self, - place: PlaceTy<'tcx, M::PointerTag> - ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { - let op = match place.place { - Place::Ptr(mplace) => { - Operand::Indirect(mplace) - } - Place::Local { frame, local } => - *self.stack[frame].locals[local].access()? - }; - Ok(OpTy { op, layout: place.layout }) - } - pub fn raw_const_to_mplace( &self, raw: RawConst<'tcx>, diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index be50daa1709..72d60f259e7 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -7,7 +7,7 @@ use rustc::mir::interpret::{EvalResult, PointerArithmetic, EvalErrorKind, Scalar}; use super::{ - EvalContext, Machine, Immediate, OpTy, PlaceTy, MPlaceTy, Operand, StackPopCleanup + EvalContext, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup }; impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { @@ -418,8 +418,10 @@ fn eval_fn_call( let mut args = args.to_vec(); let pointee = args[0].layout.ty.builtin_deref(true).unwrap().ty; let fake_fat_ptr_ty = self.tcx.mk_mut_ptr(pointee); - args[0].layout = self.layout_of(fake_fat_ptr_ty)?.field(self, 0)?; - args[0].op = Operand::Immediate(Immediate::Scalar(ptr.ptr.into())); // strip vtable + args[0] = OpTy::from(ImmTy { // strip vtable + layout: self.layout_of(fake_fat_ptr_ty)?.field(self, 0)?, + imm: Immediate::Scalar(ptr.ptr.into()) + }); trace!("Patched self operand to {:#?}", args[0]); // recurse with concrete function self.eval_fn_call(instance, span, caller_abi, &args, dest, ret) @@ -448,8 +450,8 @@ fn drop_in_place( _ => (instance, place), }; - let arg = OpTy { - op: Operand::Immediate(place.to_ref()), + let arg = ImmTy { + imm: place.to_ref(), layout: self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?, }; @@ -460,7 +462,7 @@ fn drop_in_place( instance, span, Abi::Rust, - &[arg], + &[arg.into()], Some(dest.into()), Some(target), ) diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 65d7060b544..1b0a9b17d36 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -22,6 +22,10 @@ pub fn get_vtable( let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref)); if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) { + // This means we guarantee that there are no duplicate vtables, we will + // always use the same vtable for the same (Type, Trait) combination. + // That's not what happens in rustc, but emulating per-crate deduplication + // does not sound like it actually makes anything any better. return Ok(Pointer::from(vtable).with_default_tag()); } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 018f71c39e5..d8d24c06f5a 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -18,10 +18,9 @@ HasTyCtxt, TargetDataLayout, HasDataLayout, }; -use crate::interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind}; +use crate::interpret::{EvalContext, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind}; use crate::const_eval::{ CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx, - lazy_const_to_op, }; use crate::transform::{MirPass, MirSource}; @@ -254,7 +253,7 @@ fn eval_constant( source_info: SourceInfo, ) -> Option> { self.ecx.tcx.span = source_info.span; - match lazy_const_to_op(&self.ecx, *c.literal, c.ty) { + match self.ecx.lazy_const_to_op(*c.literal, c.ty) { Ok(op) => { Some((op, c.span)) }, @@ -345,15 +344,15 @@ fn const_prop( Rvalue::Len(_) => None, Rvalue::NullaryOp(NullOp::SizeOf, ty) => { type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some(( - OpTy { - op: interpret::Operand::Immediate(Immediate::Scalar( + ImmTy { + imm: Immediate::Scalar( Scalar::Bits { bits: n as u128, size: self.tcx.data_layout.pointer_size.bytes() as u8, }.into() - )), + ), layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?, - }, + }.into(), span, ))) } @@ -388,11 +387,11 @@ fn const_prop( // Now run the actual operation. this.ecx.unary_op(op, prim, arg.layout) })?; - let res = OpTy { - op: interpret::Operand::Immediate(Immediate::Scalar(val.into())), + let res = ImmTy { + imm: Immediate::Scalar(val.into()), layout: place_layout, }; - Some((res, span)) + Some((res.into(), span)) } Rvalue::CheckedBinaryOp(op, ref left, ref right) | Rvalue::BinaryOp(op, ref left, ref right) => { @@ -462,11 +461,11 @@ fn const_prop( } Immediate::Scalar(val.into()) }; - let res = OpTy { - op: interpret::Operand::Immediate(val), + let res = ImmTy { + imm: val, layout: place_layout, }; - Some((res, span)) + Some((res.into(), span)) }, } }