From e53e9b9e63be157efeac9212dc05b3e9c8d0fd19 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 28 Aug 2017 15:27:50 +0200 Subject: [PATCH] Deduplicate writing null case of struct wrapped nullable pointers --- src/librustc_mir/interpret/eval_context.rs | 51 ++++++++++++++-------- src/librustc_mir/interpret/step.rs | 21 ++------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 79f170ace6c8..39ead337906f 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -767,25 +767,11 @@ pub(super) fn eval_rvalue_into_lvalue( let operand_ty = self.operand_ty(operand); assert_eq!(self.type_size(operand_ty)?, Some(0)); } - let (offset, TyAndPacked { ty, packed: _ }) = - self.nonnull_offset_and_ty( - dest_ty, - nndiscr, - discrfield_source, - )?; - // TODO: The packed flag is ignored - - // FIXME(solson) - let dest = self.force_allocation(dest)?.to_ptr()?; - - let dest = dest.offset(offset.bytes(), &self)?; - let dest_size = self.type_size(ty)?.expect( - "bad StructWrappedNullablePointer discrfield", - ); - self.memory.write_maybe_aligned_mut( - !nonnull.packed, - // The sign does not matter for 0 - |mem| mem.write_primval(dest, PrimVal::Bytes(0), dest_size, false), + self.write_struct_wrapped_null_pointer( + dest_ty, + nndiscr, + discrfield_source, + dest, )?; } } else { @@ -1021,6 +1007,33 @@ pub(super) fn eval_rvalue_into_lvalue( Ok(()) } + pub(crate) fn write_struct_wrapped_null_pointer( + &mut self, + dest_ty: ty::Ty<'tcx>, + nndiscr: u64, + discrfield_source: &layout::FieldPath, + dest: Lvalue, + ) -> EvalResult<'tcx> { + let (offset, TyAndPacked { ty, packed }) = self.nonnull_offset_and_ty( + dest_ty, + nndiscr, + discrfield_source, + )?; + let nonnull = self.force_allocation(dest)?.to_ptr()?.offset( + offset.bytes(), + &self, + )?; + trace!("struct wrapped nullable pointer type: {}", ty); + // only the pointer part of a fat pointer is used for this space optimization + let discr_size = self.type_size(ty)?.expect( + "bad StructWrappedNullablePointer discrfield", + ); + self.memory.write_maybe_aligned_mut(!packed, |mem| { + // We're writing 0, signedness does not matter + mem.write_primval(nonnull, PrimVal::Bytes(0), discr_size, false) + }) + } + pub(super) fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { match ty.sty { ty::TyRawPtr(ref tam) | diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 9a6f72c7bfde..ea90e39489d5 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -11,8 +11,8 @@ use rustc::ty::layout::Layout; use rustc::ty::subst::Substs; -use super::{EvalResult, EvalContext, StackPopCleanup, TyAndPacked, PtrAndAlign, GlobalId, Lvalue, - HasMemory, MemoryKind, Machine, PrimVal}; +use super::{EvalResult, EvalContext, StackPopCleanup, PtrAndAlign, GlobalId, Lvalue, + MemoryKind, Machine, PrimVal}; use syntax::codemap::Span; use syntax::ast::Mutability; @@ -125,26 +125,13 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> { ref discrfield_source, .. } => { - // TODO: There's some duplication between here and eval_rvalue_into_lvalue if variant_index as u64 != nndiscr { - let (offset, TyAndPacked { ty, packed }) = self.nonnull_offset_and_ty( + self.write_struct_wrapped_null_pointer( dest_ty, nndiscr, discrfield_source, + dest, )?; - let nonnull = self.force_allocation(dest)?.to_ptr()?.offset( - offset.bytes(), - &self, - )?; - trace!("struct wrapped nullable pointer type: {}", ty); - // only the pointer part of a fat pointer is used for this space optimization - let discr_size = self.type_size(ty)?.expect( - "bad StructWrappedNullablePointer discrfield", - ); - self.write_maybe_aligned_mut(!packed, |ectx| { - // We're writing 0, signedness does not matter - ectx.memory.write_primval(nonnull, PrimVal::Bytes(0), discr_size, false) - })?; } }