X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_const_eval%2Fsrc%2Finterpret%2Fplace.rs;h=29d2312612ea9fb8fa5d5dc7e5de03b54baa5320;hb=9e772114e6a17498f1ba27ba96693012788972e2;hp=4d0125bf395d69174206a67d238edb94694d4e54;hpb=1b41a38f523714d37f0e8257bcceb505166efd68;p=rust.git diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 4d0125bf395..c47cfe8bb69 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -2,6 +2,8 @@ //! into a place. //! All high-level functions to write to memory work on places as destinations. +use either::{Either, Left, Right}; + use rustc_ast::Mutability; use rustc_middle::mir; use rustc_middle::ty; @@ -252,36 +254,36 @@ pub(super) fn vtable(&self) -> Scalar { // These are defined here because they produce a place. impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { #[inline(always)] - pub fn try_as_mplace(&self) -> Result, ImmTy<'tcx, Prov>> { + pub fn as_mplace_or_imm(&self) -> Either, ImmTy<'tcx, Prov>> { match **self { Operand::Indirect(mplace) => { - Ok(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() }) + Left(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() }) } - Operand::Immediate(imm) => Err(ImmTy::from_immediate(imm, self.layout)), + Operand::Immediate(imm) => Right(ImmTy::from_immediate(imm, self.layout)), } } #[inline(always)] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> { - self.try_as_mplace().unwrap() + self.as_mplace_or_imm().left().unwrap() } } impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> { /// A place is either an mplace or some local. #[inline] - pub fn try_as_mplace(&self) -> Result, (usize, mir::Local)> { + pub fn as_mplace_or_local(&self) -> Either, (usize, mir::Local)> { match **self { - Place::Ptr(mplace) => Ok(MPlaceTy { mplace, layout: self.layout, align: self.align }), - Place::Local { frame, local } => Err((frame, local)), + Place::Ptr(mplace) => Left(MPlaceTy { mplace, layout: self.layout, align: self.align }), + Place::Local { frame, local } => Right((frame, local)), } } #[inline(always)] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> { - self.try_as_mplace().unwrap() + self.as_mplace_or_local().left().unwrap() } } @@ -316,8 +318,7 @@ pub fn ref_to_mplace( Ok(MPlaceTy { mplace, layout, align }) } - /// Take an operand, representing a pointer, and dereference it to a place -- that - /// will always be a MemPlace. Lives in `place.rs` because it creates a place. + /// Take an operand, representing a pointer, and dereference it to a place. #[instrument(skip(self), level = "debug")] pub fn deref_operand( &self, @@ -331,7 +332,7 @@ pub fn deref_operand( } let mplace = self.ref_to_mplace(&val)?; - self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?; + self.check_mplace(mplace)?; Ok(mplace) } @@ -358,17 +359,18 @@ pub(super) fn get_place_alloc_mut( } /// Check if this mplace is dereferenceable and sufficiently aligned. - fn check_mplace_access( - &self, - mplace: MPlaceTy<'tcx, M::Provenance>, - msg: CheckInAllocMsg, - ) -> InterpResult<'tcx> { + pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> { let (size, align) = self .size_and_align_of_mplace(&mplace)? .unwrap_or((mplace.layout.size, mplace.layout.align.abi)); assert!(mplace.align <= align, "dynamic alignment less strict than static one?"); let align = M::enforce_alignment(self).then_some(align); - self.check_ptr_access_align(mplace.ptr, size, align.unwrap_or(Align::ONE), msg)?; + self.check_ptr_access_align( + mplace.ptr, + size, + align.unwrap_or(Align::ONE), + CheckInAllocMsg::DerefTest, + )?; Ok(()) } @@ -569,9 +571,9 @@ fn write_immediate_to_mplace_no_validate( } pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> { - let mplace = match dest.try_as_mplace() { - Ok(mplace) => mplace, - Err((frame, local)) => { + let mplace = match dest.as_mplace_or_local() { + Left(mplace) => mplace, + Right((frame, local)) => { match M::access_local_mut(self, frame, local)? { Operand::Immediate(local) => { *local = Immediate::Uninit; @@ -639,7 +641,7 @@ fn copy_op_no_validate( // Let us see if the layout is simple so we take a shortcut, // avoid force_allocation. let src = match self.read_immediate_raw(src)? { - Ok(src_val) => { + Right(src_val) => { // FIXME(const_prop): Const-prop can possibly evaluate an // unsized copy operation when it thinks that the type is // actually sized, due to a trivially false where-clause @@ -669,7 +671,7 @@ fn copy_op_no_validate( ) }; } - Err(mplace) => mplace, + Left(mplace) => mplace, }; // Slow path, this does not fit into an immediate. Just memcpy. trace!("copy_op: {:?} <- {:?}: {}", *dest, src, dest.layout.ty);