From 00fb45dccdec7f2f2ba006b57cfd993f8f4ff665 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Jul 2023 22:04:02 +0200 Subject: [PATCH 1/4] interpret: make write functions generic over the place type --- .../src/const_eval/valtrees.rs | 8 +- .../src/interpret/discriminant.rs | 17 +- .../src/interpret/intrinsics.rs | 2 +- .../interpret/intrinsics/caller_location.rs | 6 +- .../rustc_const_eval/src/interpret/mod.rs | 2 +- .../rustc_const_eval/src/interpret/operand.rs | 14 +- .../rustc_const_eval/src/interpret/place.rs | 226 ++++++++++-------- .../src/interpret/projection.rs | 27 +-- .../rustc_const_eval/src/interpret/step.rs | 2 +- .../rustc_const_eval/src/interpret/visitor.rs | 4 +- src/tools/miri/src/concurrency/data_race.rs | 10 +- src/tools/miri/src/concurrency/thread.rs | 2 +- src/tools/miri/src/eval.rs | 8 +- src/tools/miri/src/helpers.rs | 28 +-- src/tools/miri/src/machine.rs | 2 +- src/tools/miri/src/shims/backtrace.rs | 18 +- src/tools/miri/src/shims/env.rs | 4 +- src/tools/miri/src/shims/intrinsics/mod.rs | 2 +- src/tools/miri/src/shims/intrinsics/simd.rs | 20 +- src/tools/miri/src/shims/time.rs | 4 +- .../miri/src/shims/unix/foreign_items.rs | 20 +- src/tools/miri/src/shims/unix/fs.rs | 4 +- src/tools/miri/src/shims/unix/linux/fd.rs | 4 +- .../src/shims/unix/macos/foreign_items.rs | 2 +- src/tools/miri/src/shims/unix/sync.rs | 12 +- .../miri/src/shims/windows/foreign_items.rs | 2 +- 26 files changed, 240 insertions(+), 210 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index b519bcdf4a339..61aace8d3ea48 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -345,7 +345,7 @@ fn valtree_into_mplace<'tcx>( ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { let scalar_int = valtree.unwrap_leaf(); debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place); - ecx.write_immediate(Immediate::Scalar(scalar_int.into()), &place.into()).unwrap(); + ecx.write_immediate(Immediate::Scalar(scalar_int.into()), place).unwrap(); } ty::Ref(_, inner_ty, _) => { let mut pointee_place = create_pointee_place(ecx, *inner_ty, valtree); @@ -369,7 +369,7 @@ fn valtree_into_mplace<'tcx>( }; debug!(?imm); - ecx.write_immediate(imm, &place.into()).unwrap(); + ecx.write_immediate(imm, place).unwrap(); } ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str | ty::Slice(_) => { let branches = valtree.unwrap_branch(); @@ -452,11 +452,11 @@ fn valtree_into_mplace<'tcx>( if let Some(variant_idx) = variant_idx { // don't forget filling the place with the discriminant of the enum - ecx.write_discriminant(variant_idx, &place.into()).unwrap(); + ecx.write_discriminant(variant_idx, place).unwrap(); } debug!("dump of place after writing discriminant:"); - dump_place(ecx, place.into()); + dump_place(ecx, place.clone().into()); } _ => bug!("shouldn't have created a ValTree for {:?}", ty), } diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index aff86d5f48668..b6584daf23dee 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -5,7 +5,8 @@ use rustc_middle::{mir, ty}; use rustc_target::abi::{self, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; -use super::{ImmTy, InterpCx, InterpResult, Machine, OpTy, PlaceTy, Scalar}; +use super::place::Writeable; +use super::{ImmTy, InterpCx, InterpResult, Machine, OpTy, Scalar}; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Writes the discriminant of the given variant. @@ -13,7 +14,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn write_discriminant( &mut self, variant_index: VariantIdx, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { // Layout computation excludes uninhabited variants from consideration // therefore there's no way to represent those variants in the given layout. @@ -21,11 +22,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // discriminant, so we cannot do anything here. // When evaluating we will always error before even getting here, but ConstProp 'executes' // dead code, so we cannot ICE here. - if dest.layout.for_variant(self, variant_index).abi.is_uninhabited() { + if dest.layout().for_variant(self, variant_index).abi.is_uninhabited() { throw_ub!(UninhabitedEnumVariantWritten(variant_index)) } - match dest.layout.variants { + match dest.layout().variants { abi::Variants::Single { index } => { assert_eq!(index, variant_index); } @@ -38,8 +39,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // No need to validate that the discriminant here because the // `TyAndLayout::for_variant()` call earlier already checks the variant is valid. - let discr_val = - dest.layout.ty.discriminant_for_variant(*self.tcx, variant_index).unwrap().val; + let discr_val = dest + .layout() + .ty + .discriminant_for_variant(*self.tcx, variant_index) + .unwrap() + .val; // raw discriminants for enums are isize or bigger during // their computation, but the in-memory tag is the smallest possible diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 3f69716828053..9eb4c29049500 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -432,7 +432,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.project_index(&input, i)?.into() }; - self.copy_op(&value, &place.into(), /*allow_transmute*/ false)?; + self.copy_op(&value, &place, /*allow_transmute*/ false)?; } } sym::simd_extract => { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 44a12751743dc..948bec7464ad2 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -101,11 +101,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); // Initialize fields. - self.write_immediate(file.to_ref(self), &self.project_field(&location, 0).unwrap().into()) + self.write_immediate(file.to_ref(self), &self.project_field(&location, 0).unwrap()) .expect("writing to memory we just allocated cannot fail"); - self.write_scalar(line, &self.project_field(&location, 1).unwrap().into()) + self.write_scalar(line, &self.project_field(&location, 1).unwrap()) .expect("writing to memory we just allocated cannot fail"); - self.write_scalar(col, &self.project_field(&location, 2).unwrap().into()) + self.write_scalar(col, &self.project_field(&location, 2).unwrap()) .expect("writing to memory we just allocated cannot fail"); location diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 7974920bc14da..de5c63589636f 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -25,7 +25,7 @@ pub use self::intern::{intern_const_alloc_recursive, InternKind}; pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump}; pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind}; pub use self::operand::{ImmTy, Immediate, OpTy, Operand}; -pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy}; +pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy, Writeable}; pub use self::projection::Projectable; pub use self::terminator::FnArg; pub use self::validity::{CtfeValidationMode, RefTracking}; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index be39e63ab4f5a..828f9e019afb7 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -312,13 +312,13 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { } } -impl<'mir, 'tcx: 'mir, Prov: Provenance> Projectable<'mir, 'tcx, Prov> for ImmTy<'tcx, Prov> { +impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for ImmTy<'tcx, Prov> { #[inline(always)] fn layout(&self) -> TyAndLayout<'tcx> { self.layout } - fn meta>( + fn meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, MemPlaceMeta> { @@ -337,7 +337,7 @@ impl<'mir, 'tcx: 'mir, Prov: Provenance> Projectable<'mir, 'tcx, Prov> for ImmTy Ok(self.offset_(offset, layout, cx)) } - fn to_op>( + fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { @@ -362,15 +362,13 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { } } -impl<'mir, 'tcx: 'mir, Prov: Provenance + 'static> Projectable<'mir, 'tcx, Prov> - for OpTy<'tcx, Prov> -{ +impl<'tcx, Prov: Provenance + 'static> Projectable<'tcx, Prov> for OpTy<'tcx, Prov> { #[inline(always)] fn layout(&self) -> TyAndLayout<'tcx> { self.layout } - fn meta>( + fn meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, MemPlaceMeta> { @@ -394,7 +392,7 @@ impl<'mir, 'tcx: 'mir, Prov: Provenance + 'static> Projectable<'mir, 'tcx, Prov> } } - fn to_op>( + fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index db1239c7136aa..407b7296c729e 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -92,6 +92,14 @@ pub struct MPlaceTy<'tcx, Prov: Provenance = AllocId> { pub align: Align, } +impl<'tcx, Prov: Provenance> std::ops::Deref for MPlaceTy<'tcx, Prov> { + type Target = MemPlace; + #[inline(always)] + fn deref(&self) -> &MemPlace { + &self.mplace + } +} + #[derive(Copy, Clone, Debug)] pub enum Place { /// A place referring to a value allocated in the `Memory` system. @@ -125,14 +133,6 @@ impl<'tcx, Prov: Provenance> std::ops::Deref for PlaceTy<'tcx, Prov> { } } -impl<'tcx, Prov: Provenance> std::ops::Deref for MPlaceTy<'tcx, Prov> { - type Target = MemPlace; - #[inline(always)] - fn deref(&self) -> &MemPlace { - &self.mplace - } -} - impl<'tcx, Prov: Provenance> From> for PlaceTy<'tcx, Prov> { #[inline(always)] fn from(mplace: MPlaceTy<'tcx, Prov>) -> Self { @@ -140,20 +140,6 @@ impl<'tcx, Prov: Provenance> From> for PlaceTy<'tcx, Prov> } } -impl<'tcx, Prov: Provenance> From<&'_ MPlaceTy<'tcx, Prov>> for PlaceTy<'tcx, Prov> { - #[inline(always)] - fn from(mplace: &MPlaceTy<'tcx, Prov>) -> Self { - PlaceTy { place: Place::Ptr(**mplace), layout: mplace.layout, align: mplace.align } - } -} - -impl<'tcx, Prov: Provenance> From<&'_ mut MPlaceTy<'tcx, Prov>> for PlaceTy<'tcx, Prov> { - #[inline(always)] - fn from(mplace: &mut MPlaceTy<'tcx, Prov>) -> Self { - PlaceTy { place: Place::Ptr(**mplace), layout: mplace.layout, align: mplace.align } - } -} - impl MemPlace { #[inline(always)] pub fn from_ptr(ptr: Pointer>) -> Self { @@ -229,15 +215,13 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> { } } -impl<'mir, 'tcx: 'mir, Prov: Provenance + 'static> Projectable<'mir, 'tcx, Prov> - for MPlaceTy<'tcx, Prov> -{ +impl<'tcx, Prov: Provenance + 'static> Projectable<'tcx, Prov> for MPlaceTy<'tcx, Prov> { #[inline(always)] fn layout(&self) -> TyAndLayout<'tcx> { self.layout } - fn meta>( + fn meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, MemPlaceMeta> { @@ -258,7 +242,7 @@ impl<'mir, 'tcx: 'mir, Prov: Provenance + 'static> Projectable<'mir, 'tcx, Prov> }) } - fn to_op>( + fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { @@ -266,6 +250,54 @@ impl<'mir, 'tcx: 'mir, Prov: Provenance + 'static> Projectable<'mir, 'tcx, Prov> } } +impl<'tcx, Prov: Provenance + 'static> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> { + #[inline(always)] + fn layout(&self) -> TyAndLayout<'tcx> { + self.layout + } + + fn meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + &self, + ecx: &InterpCx<'mir, 'tcx, M>, + ) -> InterpResult<'tcx, MemPlaceMeta> { + ecx.place_meta(self) + } + + fn offset_with_meta( + &self, + offset: Size, + meta: MemPlaceMeta, + layout: TyAndLayout<'tcx>, + cx: &impl HasDataLayout, + ) -> InterpResult<'tcx, Self> { + Ok(match self.as_mplace_or_local() { + Left(mplace) => mplace.offset_with_meta(offset, meta, layout, cx)?.into(), + Right((frame, local, old_offset)) => { + assert_matches!(meta, MemPlaceMeta::None); // we couldn't store it anyway... + let new_offset = cx + .data_layout() + .offset(old_offset.unwrap_or(Size::ZERO).bytes(), offset.bytes())?; + PlaceTy { + place: Place::Local { + frame, + local, + offset: Some(Size::from_bytes(new_offset)), + }, + align: self.align.restrict_for_offset(offset), + layout, + } + } + }) + } + + fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + &self, + ecx: &InterpCx<'mir, 'tcx, M>, + ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { + ecx.place_to_op(self) + } +} + // These are defined here because they produce a place. impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { #[inline(always)] @@ -314,53 +346,51 @@ impl<'tcx, Prov: Provenance + 'static> PlaceTy<'tcx, Prov> { } } -impl<'mir, 'tcx: 'mir, Prov: Provenance + 'static> Projectable<'mir, 'tcx, Prov> - for PlaceTy<'tcx, Prov> -{ +pub trait Writeable<'tcx, Prov: Provenance>: Projectable<'tcx, Prov> { + fn as_mplace_or_local( + &self, + ) -> Either, (usize, mir::Local, Option, Align, TyAndLayout<'tcx>)>; + + fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + &self, + ecx: &mut InterpCx<'mir, 'tcx, M>, + ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>>; +} + +impl<'tcx, Prov: Provenance + 'static> Writeable<'tcx, Prov> for PlaceTy<'tcx, Prov> { #[inline(always)] - fn layout(&self) -> TyAndLayout<'tcx> { - self.layout + fn as_mplace_or_local( + &self, + ) -> Either, (usize, mir::Local, Option, Align, TyAndLayout<'tcx>)> + { + self.as_mplace_or_local() + .map_right(|(frame, local, offset)| (frame, local, offset, self.align, self.layout)) } - fn meta>( + #[inline(always)] + fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, - ecx: &InterpCx<'mir, 'tcx, M>, - ) -> InterpResult<'tcx, MemPlaceMeta> { - ecx.place_meta(self) + ecx: &mut InterpCx<'mir, 'tcx, M>, + ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> { + ecx.force_allocation(self) } +} - fn offset_with_meta( +impl<'tcx, Prov: Provenance + 'static> Writeable<'tcx, Prov> for MPlaceTy<'tcx, Prov> { + #[inline(always)] + fn as_mplace_or_local( &self, - offset: Size, - meta: MemPlaceMeta, - layout: TyAndLayout<'tcx>, - cx: &impl HasDataLayout, - ) -> InterpResult<'tcx, Self> { - Ok(match self.as_mplace_or_local() { - Left(mplace) => mplace.offset_with_meta(offset, meta, layout, cx)?.into(), - Right((frame, local, old_offset)) => { - assert_matches!(meta, MemPlaceMeta::None); // we couldn't store it anyway... - let new_offset = cx - .data_layout() - .offset(old_offset.unwrap_or(Size::ZERO).bytes(), offset.bytes())?; - PlaceTy { - place: Place::Local { - frame, - local, - offset: Some(Size::from_bytes(new_offset)), - }, - align: self.align.restrict_for_offset(offset), - layout, - } - } - }) + ) -> Either, (usize, mir::Local, Option, Align, TyAndLayout<'tcx>)> + { + Left(self.clone()) } - fn to_op>( + #[inline(always)] + fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, - ecx: &InterpCx<'mir, 'tcx, M>, - ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { - ecx.place_to_op(self) + _ecx: &mut InterpCx<'mir, 'tcx, M>, + ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> { + Ok(self.clone()) } } @@ -537,13 +567,13 @@ where pub fn write_immediate( &mut self, src: Immediate, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { self.write_immediate_no_validate(src, dest)?; - if M::enforce_validity(self, dest.layout) { + if M::enforce_validity(self, dest.layout()) { // Data got changed, better make sure it matches the type! - self.validate_operand(&self.place_to_op(dest)?)?; + self.validate_operand(&dest.to_op(self)?)?; } Ok(()) @@ -554,7 +584,7 @@ where pub fn write_scalar( &mut self, val: impl Into>, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { self.write_immediate(Immediate::Scalar(val.into()), dest) } @@ -564,7 +594,7 @@ where pub fn write_pointer( &mut self, ptr: impl Into>>, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { self.write_scalar(Scalar::from_maybe_pointer(ptr.into(), self), dest) } @@ -575,20 +605,19 @@ where fn write_immediate_no_validate( &mut self, src: Immediate, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - assert!(dest.layout.is_sized(), "Cannot write unsized immediate data"); - trace!("write_immediate: {:?} <- {:?}: {}", *dest, src, dest.layout.ty); + assert!(dest.layout().is_sized(), "Cannot write unsized immediate data"); // See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`, // but not factored as a separate function. - let mplace = match dest.place { - Place::Local { frame, local, offset } => { + let mplace = match dest.as_mplace_or_local() { + Right((frame, local, offset, align, layout)) => { if offset.is_some() { // This has been projected to a part of this local. We could have complicated // logic to still keep this local as an `Operand`... but it's much easier to // just fall back to the indirect path. - *self.force_allocation(dest)? + dest.force_mplace(self)? } else { match M::access_local_mut(self, frame, local)? { Operand::Immediate(local_val) => { @@ -623,16 +652,16 @@ where } Operand::Indirect(mplace) => { // The local is in memory, go on below. - *mplace + MPlaceTy { mplace: *mplace, align, layout } } } } } - Place::Ptr(mplace) => mplace, // already referring to memory + Left(mplace) => mplace, // already referring to memory }; // This is already in memory, write there. - self.write_immediate_to_mplace_no_validate(src, dest.layout, dest.align, mplace) + self.write_immediate_to_mplace_no_validate(src, mplace.layout, mplace.align, mplace.mplace) } /// Write an immediate to memory. @@ -696,16 +725,19 @@ where } } - pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> { + pub fn write_uninit( + &mut self, + dest: &impl Writeable<'tcx, M::Provenance>, + ) -> InterpResult<'tcx> { let mplace = match dest.as_mplace_or_local() { Left(mplace) => mplace, - Right((frame, local, offset)) => { + Right((frame, local, offset, align, layout)) => { if offset.is_some() { // This has been projected to a part of this local. We could have complicated // logic to still keep this local as an `Operand`... but it's much easier to // just fall back to the indirect path. // FIXME: share the logic with `write_immediate_no_validate`. - self.force_allocation(dest)? + dest.force_mplace(self)? } else { match M::access_local_mut(self, frame, local)? { Operand::Immediate(local) => { @@ -714,7 +746,7 @@ where } Operand::Indirect(mplace) => { // The local is in memory, go on below. - MPlaceTy { mplace: *mplace, layout: dest.layout, align: dest.align } + MPlaceTy { mplace: *mplace, layout, align } } } } @@ -735,14 +767,14 @@ where pub fn copy_op( &mut self, src: &OpTy<'tcx, M::Provenance>, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, allow_transmute: bool, ) -> InterpResult<'tcx> { self.copy_op_no_validate(src, dest, allow_transmute)?; - if M::enforce_validity(self, dest.layout) { + if M::enforce_validity(self, dest.layout()) { // Data got changed, better make sure it matches the type! - self.validate_operand(&self.place_to_op(dest)?)?; + self.validate_operand(&dest.to_op(self)?)?; } Ok(()) @@ -756,19 +788,19 @@ where fn copy_op_no_validate( &mut self, src: &OpTy<'tcx, M::Provenance>, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, allow_transmute: bool, ) -> InterpResult<'tcx> { // We do NOT compare the types for equality, because well-typed code can // actually "transmute" `&mut T` to `&T` in an assignment without a cast. let layout_compat = - mir_assign_valid_types(*self.tcx, self.param_env, src.layout, dest.layout); + mir_assign_valid_types(*self.tcx, self.param_env, src.layout, dest.layout()); if !allow_transmute && !layout_compat { span_bug!( self.cur_span(), "type mismatch when copying!\nsrc: {:?},\ndest: {:?}", src.layout.ty, - dest.layout.ty, + dest.layout().ty, ); } @@ -784,10 +816,10 @@ where if src.layout.is_unsized() { throw_inval!(SizeOfUnsizedType(src.layout.ty)); } - if dest.layout.is_unsized() { - throw_inval!(SizeOfUnsizedType(dest.layout.ty)); + if dest.layout().is_unsized() { + throw_inval!(SizeOfUnsizedType(dest.layout().ty)); } - assert_eq!(src.layout.size, dest.layout.size); + assert_eq!(src.layout.size, dest.layout().size); // Yay, we got a value that we can write directly. return if layout_compat { self.write_immediate_no_validate(*src_val, dest) @@ -796,7 +828,7 @@ where // loaded using the offsets defined by `src.layout`. When we put this back into // the destination, we have to use the same offsets! So (a) we make sure we // write back to memory, and (b) we use `dest` *with the source layout*. - let dest_mem = self.force_allocation(dest)?; + let dest_mem = dest.force_mplace(self)?; self.write_immediate_to_mplace_no_validate( *src_val, src.layout, @@ -808,9 +840,9 @@ where Left(mplace) => mplace, }; // Slow path, this does not fit into an immediate. Just memcpy. - trace!("copy_op: {:?} <- {:?}: {}", *dest, src, dest.layout.ty); + trace!("copy_op: {:?} <- {:?}: {}", *dest, src, dest.layout().ty); - let dest = self.force_allocation(&dest)?; + let dest = dest.force_mplace(self)?; let Some((dest_size, _)) = self.size_and_align_of_mplace(&dest)? else { span_bug!(self.cur_span(), "copy_op needs (dynamically) sized values") }; @@ -928,7 +960,7 @@ where operands: &IndexSlice>, dest: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - self.write_uninit(&dest)?; + self.write_uninit(dest)?; let (variant_index, variant_dest, active_field_index) = match *kind { mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { let variant_dest = self.project_downcast(dest, variant_index)?; @@ -945,7 +977,7 @@ where let op = self.eval_operand(operand, Some(field_dest.layout))?; self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?; } - self.write_discriminant(variant_index, &dest) + self.write_discriminant(variant_index, dest) } pub fn raw_const_to_mplace( @@ -983,7 +1015,7 @@ where /// Turn a `dyn* Trait` type into an value with the actual dynamic type. /// Also returns the vtable. - pub(super) fn unpack_dyn_star>( + pub(super) fn unpack_dyn_star>( &self, val: &P, ) -> InterpResult<'tcx, (P, Pointer>)> { diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index ddcbc8350aaee..bce43aedb69c6 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -16,21 +16,20 @@ use rustc_target::abi::HasDataLayout; use rustc_target::abi::Size; use rustc_target::abi::{self, VariantIdx}; -use super::MPlaceTy; -use super::{InterpCx, InterpResult, Machine, MemPlaceMeta, OpTy, Provenance, Scalar}; +use super::{InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Provenance, Scalar}; /// A thing that we can project into, and that has a layout. -pub trait Projectable<'mir, 'tcx: 'mir, Prov: Provenance>: Sized { +pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { /// Get the layout. fn layout(&self) -> TyAndLayout<'tcx>; /// Get the metadata of a wide value. - fn meta>( + fn meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, MemPlaceMeta>; - fn len>( + fn len<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, u64> { @@ -67,7 +66,7 @@ pub trait Projectable<'mir, 'tcx: 'mir, Prov: Provenance>: Sized { /// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for /// reading from this thing. - fn to_op>( + fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>>; @@ -85,7 +84,7 @@ where /// /// This also works for arrays, but then the `usize` index type is restricting. /// For indexing into arrays, use `mplace_index`. - pub fn project_field>( + pub fn project_field>( &self, base: &P, field: usize, @@ -128,7 +127,7 @@ where } /// Downcasting to an enum variant. - pub fn project_downcast>( + pub fn project_downcast>( &self, base: &P, variant: VariantIdx, @@ -149,7 +148,7 @@ where } /// Compute the offset and field layout for accessing the given index. - pub fn project_index>( + pub fn project_index>( &self, base: &P, index: u64, @@ -178,7 +177,7 @@ where base.offset(offset, field_layout, self) } - fn project_constant_index>( + fn project_constant_index>( &self, base: &P, offset: u64, @@ -204,7 +203,7 @@ where /// Iterates over all fields of an array. Much more efficient than doing the /// same by repeatedly calling `operand_index`. - pub fn project_array_fields<'a, P: Projectable<'mir, 'tcx, M::Provenance>>( + pub fn project_array_fields<'a, P: Projectable<'tcx, M::Provenance>>( &self, base: &'a P, ) -> InterpResult<'tcx, impl Iterator> + 'a> @@ -224,7 +223,7 @@ where } /// Subslicing - fn project_subslice>( + fn project_subslice>( &self, base: &P, from: u64, @@ -284,9 +283,7 @@ where #[instrument(skip(self), level = "trace")] pub fn project

(&self, base: &P, proj_elem: mir::PlaceElem<'tcx>) -> InterpResult<'tcx, P> where - P: Projectable<'mir, 'tcx, M::Provenance> - + From> - + std::fmt::Debug, + P: Projectable<'tcx, M::Provenance> + From> + std::fmt::Debug, { use rustc_middle::mir::ProjectionElem::*; Ok(match proj_elem { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 9182d23128fe2..1f2d04f400894 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -198,7 +198,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // Write the src to the first element. let first = self.project_index(&dest, 0)?; - self.copy_op(&src, &first.into(), /*allow_transmute*/ false)?; + self.copy_op(&src, &first, /*allow_transmute*/ false)?; // This is performance-sensitive code for big static/const arrays! So we // avoid writing each operand individually and instead just make many copies diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 4ec19d9e655b7..531e2bd3ee064 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -13,9 +13,7 @@ use super::{InterpCx, MPlaceTy, Machine, Projectable}; /// How to traverse a value and what to do when we are at the leaves. pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { - type V: Projectable<'mir, 'tcx, M::Provenance> - + From> - + std::fmt::Debug; + type V: Projectable<'tcx, M::Provenance> + From>; /// The visitor must have an `InterpCx` in it. fn ecx(&self) -> &InterpCx<'mir, 'tcx, M>; diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 84ef27f736596..4db55abd2323f 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -490,7 +490,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { this.atomic_access_check(dest)?; this.validate_overlapping_atomic(dest)?; - this.allow_data_races_mut(move |this| this.write_scalar(val, &dest.into()))?; + this.allow_data_races_mut(move |this| this.write_scalar(val, dest))?; this.validate_atomic_store(dest, atomic)?; // FIXME: it's not possible to get the value before write_scalar. A read_scalar will cause // side effects from a read the program did not perform. So we have to initialise @@ -518,7 +518,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { // Atomics wrap around on overflow. let val = this.binary_op(op, &old, rhs)?; let val = if neg { this.unary_op(mir::UnOp::Not, &val)? } else { val }; - this.allow_data_races_mut(|this| this.write_immediate(*val, &place.into()))?; + this.allow_data_races_mut(|this| this.write_immediate(*val, place))?; this.validate_atomic_rmw(place, atomic)?; @@ -539,7 +539,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { this.validate_overlapping_atomic(place)?; let old = this.allow_data_races_mut(|this| this.read_scalar(&place.into()))?; - this.allow_data_races_mut(|this| this.write_scalar(new, &place.into()))?; + this.allow_data_races_mut(|this| this.write_scalar(new, place))?; this.validate_atomic_rmw(place, atomic)?; @@ -569,7 +569,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { if lt { &rhs } else { &old } }; - this.allow_data_races_mut(|this| this.write_immediate(**new_val, &place.into()))?; + this.allow_data_races_mut(|this| this.write_immediate(**new_val, place))?; this.validate_atomic_rmw(place, atomic)?; @@ -621,7 +621,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { // if successful, perform a full rw-atomic validation // otherwise treat this as an atomic load with the fail ordering. if cmpxchg_success { - this.allow_data_races_mut(|this| this.write_scalar(new, &place.into()))?; + this.allow_data_races_mut(|this| this.write_scalar(new, place))?; this.validate_atomic_rmw(place, success)?; this.buffered_atomic_rmw(new, place, success, old.to_scalar())?; } else { diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 25c8df43ee26c..9c11ad85aefd3 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -834,7 +834,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if let Some(thread_info_place) = thread { this.write_scalar( Scalar::from_uint(new_thread_id.to_u32(), thread_info_place.layout.size), - &thread_info_place.into(), + &thread_info_place, )?; } diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 4f7b70649a934..36c43053648cb 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -321,7 +321,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into())?; for (idx, arg) in argvs.into_iter().enumerate() { let place = ecx.project_field(&argvs_place, idx)?; - ecx.write_immediate(arg, &place.into())?; + ecx.write_immediate(arg, &place)?; } ecx.mark_immutable(&argvs_place); // A pointer to that place is the 3rd argument for main. @@ -330,7 +330,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( { let argc_place = ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?; - ecx.write_scalar(argc, &argc_place.into())?; + ecx.write_scalar(argc, &argc_place)?; ecx.mark_immutable(&argc_place); ecx.machine.argc = Some(*argc_place); @@ -338,7 +338,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( ecx.layout_of(Ty::new_imm_ptr(tcx, tcx.types.unit))?, MiriMemoryKind::Machine.into(), )?; - ecx.write_immediate(argv, &argv_place.into())?; + ecx.write_immediate(argv, &argv_place)?; ecx.mark_immutable(&argv_place); ecx.machine.argv = Some(*argv_place); } @@ -355,7 +355,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( // Store the UTF-16 string. We just allocated so we know the bounds are fine. for (idx, &c) in cmd_utf16.iter().enumerate() { let place = ecx.project_field(&cmd_place, idx)?; - ecx.write_scalar(Scalar::from_u16(c), &place.into())?; + ecx.write_scalar(Scalar::from_u16(c), &place)?; } ecx.mark_immutable(&cmd_place); } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index f6a438f5d629b..7e9f9c05c0cdb 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -231,7 +231,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } /// Project to the given *named* field (which must be a struct or union type). - fn project_field_named>( + fn project_field_named>( &self, base: &P, name: &str, @@ -252,13 +252,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn write_int( &mut self, i: impl Into, - dest: &PlaceTy<'tcx, Provenance>, + dest: &impl Writeable<'tcx, Provenance>, ) -> InterpResult<'tcx> { - assert!(dest.layout.abi.is_scalar(), "write_int on non-scalar type {}", dest.layout.ty); - let val = if dest.layout.abi.is_signed() { - Scalar::from_int(i, dest.layout.size) + assert!(dest.layout().abi.is_scalar(), "write_int on non-scalar type {}", dest.layout().ty); + let val = if dest.layout().abi.is_signed() { + Scalar::from_int(i, dest.layout().size) } else { - Scalar::from_uint(u64::try_from(i.into()).unwrap(), dest.layout.size) + Scalar::from_uint(u64::try_from(i.into()).unwrap(), dest.layout().size) }; self.eval_context_mut().write_scalar(val, dest) } @@ -267,12 +267,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn write_int_fields( &mut self, values: &[i128], - dest: &MPlaceTy<'tcx, Provenance>, + dest: &impl Writeable<'tcx, Provenance>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); for (idx, &val) in values.iter().enumerate() { let field = this.project_field(dest, idx)?; - this.write_int(val, &field.into())?; + this.write_int(val, &field)?; } Ok(()) } @@ -281,18 +281,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn write_int_fields_named( &mut self, values: &[(&str, i128)], - dest: &MPlaceTy<'tcx, Provenance>, + dest: &impl Writeable<'tcx, Provenance>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); for &(name, val) in values.iter() { let field = this.project_field_named(dest, name)?; - this.write_int(val, &field.into())?; + this.write_int(val, &field)?; } Ok(()) } /// Write a 0 of the appropriate size to `dest`. - fn write_null(&mut self, dest: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { + fn write_null(&mut self, dest: &impl Writeable<'tcx, Provenance>) -> InterpResult<'tcx> { self.write_int(0, dest) } @@ -606,7 +606,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Allocate new place, set initial value to 0. let errno_layout = this.machine.layouts.u32; let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into())?; - this.write_scalar(Scalar::from_u32(0), &errno_place.into())?; + this.write_scalar(Scalar::from_u32(0), &errno_place)?; this.active_thread_mut().last_error = Some(errno_place); Ok(errno_place) } @@ -616,7 +616,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn set_last_error(&mut self, scalar: Scalar) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let errno_place = this.last_error_place()?; - this.write_scalar(scalar, &errno_place.into()) + this.write_scalar(scalar, &errno_place) } /// Gets the last error variable. @@ -785,7 +785,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, ()> { let this = self.eval_context_mut(); let value_place = this.deref_operand_and_offset(op, offset, base_layout, value_layout)?; - this.write_scalar(value, &value_place.into()) + this.write_scalar(value, &value_place) } /// Parse a `timespec` struct and return it as a `std::time::Duration`. It returns `None` diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index a8f89d56f6d9e..8d24d9748bf91 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -651,7 +651,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { val: ImmTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?; - this.write_immediate(*val, &place.into())?; + this.write_immediate(*val, &place)?; Self::add_extern_static(this, name, place.ptr); Ok(()) } diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index e4aa7467cbe04..e89b2e01a39a8 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -85,7 +85,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { for (i, ptr) in ptrs.into_iter().enumerate() { let place = this.project_index(&alloc, i as u64)?; - this.write_pointer(ptr, &place.into())?; + this.write_pointer(ptr, &place)?; } this.write_immediate( @@ -106,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let op_place = buf_place.offset(offset, ptr_layout, this)?; - this.write_pointer(ptr, &op_place.into())?; + this.write_pointer(ptr, &op_place)?; } } _ => throw_unsup_format!("unknown `miri_get_backtrace` flags {}", flags), @@ -196,33 +196,33 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_immediate( name_alloc.to_ref(this), - &this.project_field(&dest, 0)?.into(), + &this.project_field(&dest, 0)?, )?; this.write_immediate( filename_alloc.to_ref(this), - &this.project_field(&dest, 1)?.into(), + &this.project_field(&dest, 1)?, )?; } 1 => { this.write_scalar( Scalar::from_target_usize(name.len().try_into().unwrap(), this), - &this.project_field(&dest, 0)?.into(), + &this.project_field(&dest, 0)?, )?; this.write_scalar( Scalar::from_target_usize(filename.len().try_into().unwrap(), this), - &this.project_field(&dest, 1)?.into(), + &this.project_field(&dest, 1)?, )?; } _ => throw_unsup_format!("unknown `miri_resolve_frame` flags {}", flags), } - this.write_scalar(Scalar::from_u32(lineno), &this.project_field(&dest, 2)?.into())?; - this.write_scalar(Scalar::from_u32(colno), &this.project_field(&dest, 3)?.into())?; + this.write_scalar(Scalar::from_u32(lineno), &this.project_field(&dest, 2)?)?; + this.write_scalar(Scalar::from_u32(colno), &this.project_field(&dest, 3)?)?; // Support a 4-field struct for now - this is deprecated // and slated for removal. if num_fields == 5 { - this.write_pointer(fn_ptr, &this.project_field(&dest, 4)?.into())?; + this.write_pointer(fn_ptr, &this.project_field(&dest, 4)?)?; } Ok(()) diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index f98fd0431ae63..8c72c4d3a4212 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -457,9 +457,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let vars_place = this.allocate(vars_layout, MiriMemoryKind::Runtime.into())?; for (idx, var) in vars.into_iter().enumerate() { let place = this.project_field(&vars_place, idx)?; - this.write_pointer(var, &place.into())?; + this.write_pointer(var, &place)?; } - this.write_pointer(vars_place.ptr, &this.machine.env_vars.environ.unwrap().into())?; + this.write_pointer(vars_place.ptr, &this.machine.env_vars.environ.unwrap())?; Ok(()) } diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index ca2c1652dc199..cb8e7c1471036 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -102,7 +102,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "volatile_store" => { let [place, dest] = check_arg_count(args)?; let place = this.deref_operand(place)?; - this.copy_op(dest, &place.into(), /*allow_transmute*/ false)?; + this.copy_op(dest, &place, /*allow_transmute*/ false)?; } "write_bytes" | "volatile_set_memory" => { diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index 3afe5214f08b2..ed997bad1ef4c 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -104,7 +104,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } }; - this.write_scalar(val, &dest.into())?; + this.write_scalar(val, &dest)?; } } #[rustfmt::skip] @@ -217,7 +217,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fmin_op(&left, &right)? } }; - this.write_scalar(val, &dest.into())?; + this.write_scalar(val, &dest)?; } } "fma" => { @@ -258,7 +258,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Scalar::from_u64(res.to_bits()) } }; - this.write_scalar(val, &dest.into())?; + this.write_scalar(val, &dest)?; } } #[rustfmt::skip] @@ -378,7 +378,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let dest = this.project_index(&dest, i)?; let val = if simd_element_to_bool(mask)? { yes } else { no }; - this.write_immediate(*val, &dest.into())?; + this.write_immediate(*val, &dest)?; } } "select_bitmask" => { @@ -408,7 +408,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let dest = this.project_index(&dest, i.into())?; let val = if mask != 0 { yes } else { no }; - this.write_immediate(*val, &dest.into())?; + this.write_immediate(*val, &dest)?; } for i in dest_len..bitmask_len { // If the mask is "padded", ensure that padding is all-zero. @@ -472,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { to_ty = dest.layout.ty, ), }; - this.write_immediate(val, &dest.into())?; + this.write_immediate(val, &dest)?; } } "shuffle" => { @@ -513,7 +513,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}", ); }; - this.write_immediate(*val, &dest.into())?; + this.write_immediate(*val, &dest)?; } } "gather" => { @@ -539,7 +539,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } else { passthru }; - this.write_immediate(*val, &dest.into())?; + this.write_immediate(*val, &dest)?; } } "scatter" => { @@ -558,7 +558,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if simd_element_to_bool(mask)? { let place = this.deref_operand(&ptr.into())?; - this.write_immediate(*value, &place.into())?; + this.write_immediate(*value, &place)?; } } } @@ -588,7 +588,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We have to force the place type to be an int so that we can write `res` into it. let mut dest = this.force_allocation(dest)?; dest.layout = this.machine.layouts.uint(dest.layout.size).unwrap(); - this.write_int(res, &dest.into())?; + this.write_int(res, &dest)?; } name => throw_unsup_format!("unimplemented intrinsic: `simd_{name}`"), diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index c761c45a5a1c8..6667c4d751ffe 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -158,7 +158,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { })?; this.write_scalar( Scalar::from_i64(qpc), - &this.deref_operand(lpPerformanceCount_op)?.into(), + &this.deref_operand(lpPerformanceCount_op)?, )?; Ok(Scalar::from_i32(-1)) // return non-zero on success } @@ -179,7 +179,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // and thus 10^9 counts per second. this.write_scalar( Scalar::from_i64(1_000_000_000), - &this.deref_operand_as(lpFrequency_op, this.machine.layouts.u64)?.into(), + &this.deref_operand_as(lpFrequency_op, this.machine.layouts.u64)?, )?; Ok(Scalar::from_i32(-1)) // Return non-zero on success } diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 14297845d3dbb..5f3c15c587499 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -201,14 +201,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_int(einval, dest)?; } else { if size == 0 { - this.write_null(&ret.into())?; + this.write_null(&ret)?; } else { let ptr = this.allocate_ptr( Size::from_bytes(size), Align::from_bytes(align).unwrap(), MiriMemoryKind::C.into(), )?; - this.write_pointer(ptr, &ret.into())?; + this.write_pointer(ptr, &ret)?; } this.write_null(dest)?; } @@ -293,7 +293,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Create key and write it into the memory where `key_ptr` wants it. let key = this.machine.tls.create_tls_key(dtor, key_layout.size)?; - this.write_scalar(Scalar::from_uint(key, key_layout.size), &key_place.into())?; + this.write_scalar(Scalar::from_uint(key, key_layout.size), &key_place)?; // Return success (`0`). this.write_null(dest)?; @@ -508,7 +508,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [_attr, guard_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let guard_size = this.deref_operand(guard_size)?; let guard_size_layout = this.libc_ty_layout("size_t"); - this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size.into())?; + this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?; // Return success (`0`). this.write_null(dest)?; @@ -538,11 +538,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar( Scalar::from_uint(this.machine.stack_addr, this.pointer_size()), - &addr_place.into(), + &addr_place, )?; this.write_scalar( Scalar::from_uint(this.machine.stack_size, this.pointer_size()), - &size_place.into(), + &size_place, )?; // Return success (`0`). @@ -587,20 +587,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Reset all fields to `uninit` to make sure nobody reads them. // (This is a std-only shim so we are okay with such hacks.) - this.write_uninit(&pwd.into())?; + this.write_uninit(&pwd)?; // We only set the home_dir field. #[allow(deprecated)] let home_dir = std::env::home_dir().unwrap(); let (written, _) = this.write_path_to_c_str(&home_dir, buf, buflen)?; let pw_dir = this.project_field_named(&pwd, "pw_dir")?; - this.write_pointer(buf, &pw_dir.into())?; + this.write_pointer(buf, &pw_dir)?; if written { - this.write_pointer(pwd.ptr, &result.into())?; + this.write_pointer(pwd.ptr, &result)?; this.write_null(dest)?; } else { - this.write_null(&result.into())?; + this.write_null(&result)?; this.write_scalar(this.eval_libc("ERANGE"), dest)?; } } diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 3da6c17f3b0b7..fe5b01e761094 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -1457,13 +1457,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { )?; let result_place = this.deref_operand(result_op)?; - this.write_scalar(this.read_scalar(entry_op)?, &result_place.into())?; + this.write_scalar(this.read_scalar(entry_op)?, &result_place)?; 0 } None => { // end of stream: return 0, assign *result=NULL - this.write_null(&this.deref_operand(result_op)?.into())?; + this.write_null(&this.deref_operand(result_op)?)?; 0 } Some(Err(e)) => diff --git a/src/tools/miri/src/shims/unix/linux/fd.rs b/src/tools/miri/src/shims/unix/linux/fd.rs index 9c43651132b7f..2855157f49dd1 100644 --- a/src/tools/miri/src/shims/unix/linux/fd.rs +++ b/src/tools/miri/src/shims/unix/linux/fd.rs @@ -248,8 +248,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let sv1 = fh.insert_fd(Box::new(SocketPair)); let sv1 = ScalarInt::try_from_int(sv1, sv.layout.size).unwrap(); - this.write_scalar(sv0, &sv.into())?; - this.write_scalar(sv1, &sv.offset(sv.layout.size, sv.layout, this)?.into())?; + this.write_scalar(sv0, &sv)?; + this.write_scalar(sv1, &sv.offset(sv.layout.size, sv.layout, this)?)?; Ok(Scalar::from_i32(0)) } diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 85b950da4fe68..f42f3f90684a8 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -141,7 +141,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } else { this.write_scalar( Scalar::from_u32(size_needed.try_into().unwrap()), - &bufsize.into(), + &bufsize, )?; this.write_int(-1, dest)?; } diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 1fa0ffd8ee764..428581801d953 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -346,7 +346,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // This can always be revisited to have some external state to catch double-destroys // but not complain about the above code. See https://github.com/rust-lang/miri/pull/1933 this.write_uninit( - &this.deref_operand_as(attr_op, this.libc_ty_layout("pthread_mutexattr_t"))?.into(), + &this.deref_operand_as(attr_op, this.libc_ty_layout("pthread_mutexattr_t"))?, )?; Ok(0) @@ -500,7 +500,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // This might lead to false positives, see comment in pthread_mutexattr_destroy this.write_uninit( - &this.deref_operand_as(mutex_op, this.libc_ty_layout("pthread_mutex_t"))?.into(), + &this.deref_operand_as(mutex_op, this.libc_ty_layout("pthread_mutex_t"))?, )?; // FIXME: delete interpreter state associated with this mutex. @@ -625,7 +625,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // This might lead to false positives, see comment in pthread_mutexattr_destroy this.write_uninit( - &this.deref_operand_as(rwlock_op, this.libc_ty_layout("pthread_rwlock_t"))?.into(), + &this.deref_operand_as(rwlock_op, this.libc_ty_layout("pthread_rwlock_t"))?, )?; // FIXME: delete interpreter state associated with this rwlock. @@ -675,7 +675,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let clock_id = condattr_get_clock_id(this, attr_op)?; - this.write_scalar(Scalar::from_i32(clock_id), &this.deref_operand(clk_id_op)?.into())?; + this.write_scalar(Scalar::from_i32(clock_id), &this.deref_operand(clk_id_op)?)?; Ok(Scalar::from_i32(0)) } @@ -691,7 +691,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // This might lead to false positives, see comment in pthread_mutexattr_destroy this.write_uninit( - &this.deref_operand_as(attr_op, this.libc_ty_layout("pthread_condattr_t"))?.into(), + &this.deref_operand_as(attr_op, this.libc_ty_layout("pthread_condattr_t"))?, )?; Ok(0) @@ -868,7 +868,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // This might lead to false positives, see comment in pthread_mutexattr_destroy this.write_uninit( - &this.deref_operand_as(cond_op, this.libc_ty_layout("pthread_cond_t"))?.into(), + &this.deref_operand_as(cond_op, this.libc_ty_layout("pthread_cond_t"))?, )?; // FIXME: delete interpreter state associated with this condvar. diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index d64aa53ed9589..2f95cfb8bab1a 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -125,7 +125,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.project_field_named(&io_status_block, "Information")?; this.write_scalar( Scalar::from_target_usize(n.into(), this), - &io_status_information.into(), + &io_status_information, )?; } // Return whether this was a success. >= 0 is success. From 77ff1b83cd3279c348312e1e1f9bf6a1c1174178 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Jul 2023 22:19:18 +0200 Subject: [PATCH 2/4] interpret: make read functions generic over operand type --- .../src/const_eval/machine.rs | 2 +- .../src/const_eval/valtrees.rs | 6 +- .../rustc_const_eval/src/interpret/cast.rs | 2 +- .../src/interpret/discriminant.rs | 31 +++---- .../rustc_const_eval/src/interpret/intern.rs | 2 +- .../src/interpret/intrinsics.rs | 16 ++-- .../rustc_const_eval/src/interpret/mod.rs | 2 +- .../rustc_const_eval/src/interpret/operand.rs | 81 ++++++++++--------- .../rustc_const_eval/src/interpret/place.rs | 22 ++--- .../src/const_prop_lint.rs | 4 +- src/tools/miri/src/concurrency/data_race.rs | 10 +-- src/tools/miri/src/eval.rs | 2 +- src/tools/miri/src/helpers.rs | 10 +-- src/tools/miri/src/shims/env.rs | 4 +- src/tools/miri/src/shims/intrinsics/mod.rs | 2 +- src/tools/miri/src/shims/intrinsics/simd.rs | 54 ++++++------- src/tools/miri/src/shims/unix/linux/fd.rs | 4 +- .../src/shims/unix/macos/foreign_items.rs | 2 +- src/tools/miri/src/shims/windows/sync.rs | 2 +- 19 files changed, 130 insertions(+), 128 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 267795a6cb4ab..6630eeca27ed8 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -216,7 +216,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { let mut msg_place = self.deref_operand(&args[0])?; while msg_place.layout.ty.is_ref() { - msg_place = self.deref_operand(&msg_place.into())?; + msg_place = self.deref_operand(&msg_place)?; } let msg = Symbol::intern(self.read_str(&msg_place)?); diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 61aace8d3ea48..be5eb1558cf12 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -86,7 +86,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>( Ok(ty::ValTree::zst()) } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { - let Ok(val) = ecx.read_immediate(&place.into()) else { + let Ok(val) = ecx.read_immediate(place) else { return Err(ValTreeCreationError::Other); }; let val = val.to_scalar(); @@ -102,7 +102,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>( ty::FnPtr(_) | ty::RawPtr(_) => Err(ValTreeCreationError::NonSupportedType), ty::Ref(_, _, _) => { - let Ok(derefd_place)= ecx.deref_operand(&place.into()) else { + let Ok(derefd_place)= ecx.deref_operand(place) else { return Err(ValTreeCreationError::Other); }; debug!(?derefd_place); @@ -130,7 +130,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>( bug!("uninhabited types should have errored and never gotten converted to valtree") } - let Ok(variant) = ecx.read_discriminant(&place.into()) else { + let Ok(variant) = ecx.read_discriminant(place) else { return Err(ValTreeCreationError::Other); }; branches(ecx, place, def.variant(variant).fields.len(), def.is_enum().then_some(variant), num_nodes) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 977e49b63431a..98e853dc4d9e0 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -56,7 +56,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } CastKind::FnPtrToPtr | CastKind::PtrToPtr => { - let src = self.read_immediate(&src)?; + let src = self.read_immediate(src)?; let res = self.ptr_to_ptr(&src, cast_ty)?; self.write_immediate(res, dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index b6584daf23dee..6c35fb01a93b1 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -5,8 +5,7 @@ use rustc_middle::{mir, ty}; use rustc_target::abi::{self, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; -use super::place::Writeable; -use super::{ImmTy, InterpCx, InterpResult, Machine, OpTy, Scalar}; +use super::{ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable}; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Writes the discriminant of the given variant. @@ -97,11 +96,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[instrument(skip(self), level = "trace")] pub fn read_discriminant( &self, - op: &OpTy<'tcx, M::Provenance>, + op: &impl Readable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, VariantIdx> { - trace!("read_discriminant_value {:#?}", op.layout); + let ty = op.layout().ty; + trace!("read_discriminant_value {:#?}", op.layout()); // Get type and layout of the discriminant. - let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(*self.tcx))?; + let discr_layout = self.layout_of(ty.discriminant_ty(*self.tcx))?; trace!("discriminant type: {:?}", discr_layout.ty); // We use "discriminant" to refer to the value associated with a particular enum variant. @@ -109,20 +109,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // declared list of variants -- they can differ with explicitly assigned discriminants. // We use "tag" to refer to how the discriminant is encoded in memory, which can be either // straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`). - let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout.variants { + let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout().variants { Variants::Single { index } => { // Do some extra checks on enums. - if op.layout.ty.is_enum() { + if ty.is_enum() { // Hilariously, `Single` is used even for 0-variant enums. // (See https://github.com/rust-lang/rust/issues/89765). - if matches!(op.layout.ty.kind(), ty::Adt(def, ..) if def.variants().is_empty()) - { + if matches!(ty.kind(), ty::Adt(def, ..) if def.variants().is_empty()) { throw_ub!(UninhabitedEnumVariantRead(index)) } // For consisteny with `write_discriminant`, and to make sure that // `project_downcast` cannot fail due to strange layouts, we declare immediate UB // for uninhabited variants. - if op.layout.for_variant(self, index).abi.is_uninhabited() { + if op.layout().for_variant(self, index).abi.is_uninhabited() { throw_ub!(UninhabitedEnumVariantRead(index)) } } @@ -168,7 +167,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.cast_from_int_like(scalar, tag_val.layout, discr_layout.ty).unwrap(); let discr_bits = discr_val.assert_bits(discr_layout.size); // Convert discriminant to variant index, and catch invalid discriminants. - let index = match *op.layout.ty.kind() { + let index = match *ty.kind() { ty::Adt(adt, _) => { adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits) } @@ -222,12 +221,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .checked_add(variant_index_relative) .expect("overflow computing absolute variant idx"), ); - let variants = op - .layout - .ty - .ty_adt_def() - .expect("tagged layout for non adt") - .variants(); + let variants = + ty.ty_adt_def().expect("tagged layout for non adt").variants(); assert!(variant_index < variants.next_index()); variant_index } else { @@ -242,7 +237,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } }; // For consisteny with `write_discriminant`, and to make sure that `project_downcast` cannot fail due to strange layouts, we declare immediate UB for uninhabited variants. - if op.layout.for_variant(self, index).abi.is_uninhabited() { + if op.layout().for_variant(self, index).abi.is_uninhabited() { throw_ub!(UninhabitedEnumVariantRead(index)) } Ok(index) diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 3a7fe8bd4781b..e1088e72eb6d5 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -170,7 +170,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory let tcx = self.ecx.tcx; let ty = mplace.layout.ty; if let ty::Ref(_, referenced_ty, ref_mutability) = *ty.kind() { - let value = self.ecx.read_immediate(&mplace.into())?; + let value = self.ecx.read_immediate(mplace)?; let mplace = self.ecx.ref_to_mplace(&value)?; assert_eq!(mplace.layout.ty, referenced_ty); // Handle trait object vtables. diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 9eb4c29049500..4020d96b80efa 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -226,7 +226,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } sym::discriminant_value => { let place = self.deref_operand(&args[0])?; - let variant = self.read_discriminant(&place.into())?; + let variant = self.read_discriminant(&place)?; let discr = self.discriminant_for_variant(place.layout, variant)?; self.write_scalar(discr, dest)?; } @@ -445,7 +445,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { input_len ); self.copy_op( - &self.project_index(&input, index)?.into(), + &self.project_index(&input, index)?, dest, /*allow_transmute*/ false, )?; @@ -610,7 +610,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { count: &OpTy<'tcx, >::Provenance>, nonoverlapping: bool, ) -> InterpResult<'tcx> { - let count = self.read_target_usize(&count)?; + let count = self.read_target_usize(count)?; let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?; let (size, align) = (layout.size, layout.align.abi); // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), @@ -622,8 +622,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) })?; - let src = self.read_pointer(&src)?; - let dst = self.read_pointer(&dst)?; + let src = self.read_pointer(src)?; + let dst = self.read_pointer(dst)?; self.mem_copy(src, align, dst, align, size, nonoverlapping) } @@ -636,9 +636,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx> { let layout = self.layout_of(dst.layout.ty.builtin_deref(true).unwrap().ty)?; - let dst = self.read_pointer(&dst)?; - let byte = self.read_scalar(&byte)?.to_u8()?; - let count = self.read_target_usize(&count)?; + let dst = self.read_pointer(dst)?; + let byte = self.read_scalar(byte)?.to_u8()?; + let count = self.read_target_usize(count)?; // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index de5c63589636f..b0b553c45d432 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -24,7 +24,7 @@ pub use self::eval_context::{Frame, FrameInfo, InterpCx, LocalState, LocalValue, pub use self::intern::{intern_const_alloc_recursive, InternKind}; pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump}; pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind}; -pub use self::operand::{ImmTy, Immediate, OpTy, Operand}; +pub use self::operand::{ImmTy, Immediate, OpTy, Operand, Readable}; pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy, Writeable}; pub use self::projection::Projectable; pub use self::terminator::FnArg; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 828f9e019afb7..32a2f64832159 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -180,20 +180,6 @@ impl<'tcx, Prov: Provenance> From> for OpTy<'tcx, Prov> { } } -impl<'tcx, Prov: Provenance> From<&'_ MPlaceTy<'tcx, Prov>> for OpTy<'tcx, Prov> { - #[inline(always)] - fn from(mplace: &MPlaceTy<'tcx, Prov>) -> Self { - OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout, align: Some(mplace.align) } - } -} - -impl<'tcx, Prov: Provenance> From<&'_ mut MPlaceTy<'tcx, Prov>> for OpTy<'tcx, Prov> { - #[inline(always)] - fn from(mplace: &mut MPlaceTy<'tcx, Prov>) -> Self { - OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout, align: Some(mplace.align) } - } -} - impl<'tcx, Prov: Provenance> From> for OpTy<'tcx, Prov> { #[inline(always)] fn from(val: ImmTy<'tcx, Prov>) -> Self { @@ -201,20 +187,6 @@ impl<'tcx, Prov: Provenance> From> for OpTy<'tcx, Prov> { } } -impl<'tcx, Prov: Provenance> From<&'_ ImmTy<'tcx, Prov>> for OpTy<'tcx, Prov> { - #[inline(always)] - fn from(val: &ImmTy<'tcx, Prov>) -> Self { - OpTy { op: Operand::Immediate(val.imm), layout: val.layout, align: None } - } -} - -impl<'tcx, Prov: Provenance> From<&'_ mut ImmTy<'tcx, Prov>> for OpTy<'tcx, Prov> { - #[inline(always)] - fn from(val: &mut ImmTy<'tcx, Prov>) -> Self { - OpTy { op: Operand::Immediate(val.imm), layout: val.layout, align: None } - } -} - impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] pub fn from_scalar(val: Scalar, layout: TyAndLayout<'tcx>) -> Self { @@ -341,7 +313,7 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for ImmTy<'tcx, Prov> { &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { - Ok(self.into()) + Ok(self.clone().into()) } } @@ -400,6 +372,31 @@ impl<'tcx, Prov: Provenance + 'static> Projectable<'tcx, Prov> for OpTy<'tcx, Pr } } +pub trait Readable<'tcx, Prov: Provenance>: Projectable<'tcx, Prov> { + fn as_mplace_or_imm(&self) -> Either, ImmTy<'tcx, Prov>>; +} + +impl<'tcx, Prov: Provenance + 'static> Readable<'tcx, Prov> for OpTy<'tcx, Prov> { + #[inline(always)] + fn as_mplace_or_imm(&self) -> Either, ImmTy<'tcx, Prov>> { + self.as_mplace_or_imm() + } +} + +impl<'tcx, Prov: Provenance + 'static> Readable<'tcx, Prov> for MPlaceTy<'tcx, Prov> { + #[inline(always)] + fn as_mplace_or_imm(&self) -> Either, ImmTy<'tcx, Prov>> { + Left(self.clone()) + } +} + +impl<'tcx, Prov: Provenance> Readable<'tcx, Prov> for ImmTy<'tcx, Prov> { + #[inline(always)] + fn as_mplace_or_imm(&self) -> Either, ImmTy<'tcx, Prov>> { + Right(self.clone()) + } +} + impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`. /// Returns `None` if the layout does not permit loading this as a value. @@ -472,7 +469,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// ConstProp needs it, though. pub fn read_immediate_raw( &self, - src: &OpTy<'tcx, M::Provenance>, + src: &impl Readable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, Either, ImmTy<'tcx, M::Provenance>>> { Ok(match src.as_mplace_or_imm() { Left(ref mplace) => { @@ -492,14 +489,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn read_immediate( &self, - op: &OpTy<'tcx, M::Provenance>, + op: &impl Readable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { if !matches!( - op.layout.abi, + op.layout().abi, Abi::Scalar(abi::Scalar::Initialized { .. }) | Abi::ScalarPair(abi::Scalar::Initialized { .. }, abi::Scalar::Initialized { .. }) ) { - span_bug!(self.cur_span(), "primitive read not possible for type: {:?}", op.layout.ty); + span_bug!( + self.cur_span(), + "primitive read not possible for type: {:?}", + op.layout().ty + ); } let imm = self.read_immediate_raw(op)?.right().unwrap(); if matches!(*imm, Immediate::Uninit) { @@ -511,7 +512,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Read a scalar from a place pub fn read_scalar( &self, - op: &OpTy<'tcx, M::Provenance>, + op: &impl Readable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, Scalar> { Ok(self.read_immediate(op)?.to_scalar()) } @@ -522,16 +523,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Read a pointer from a place. pub fn read_pointer( &self, - op: &OpTy<'tcx, M::Provenance>, + op: &impl Readable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, Pointer>> { self.read_scalar(op)?.to_pointer(self) } /// Read a pointer-sized unsigned integer from a place. - pub fn read_target_usize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, u64> { + pub fn read_target_usize( + &self, + op: &impl Readable<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, u64> { self.read_scalar(op)?.to_target_usize(self) } /// Read a pointer-sized signed integer from a place. - pub fn read_target_isize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, i64> { + pub fn read_target_isize( + &self, + op: &impl Readable<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, i64> { self.read_scalar(op)?.to_target_isize(self) } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 407b7296c729e..306ad20c88348 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -18,7 +18,7 @@ use rustc_target::abi::{self, Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_V use super::{ alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand, - Pointer, Projectable, Provenance, Scalar, + Pointer, Projectable, Provenance, Readable, Scalar, }; #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] @@ -246,7 +246,7 @@ impl<'tcx, Prov: Provenance + 'static> Projectable<'tcx, Prov> for MPlaceTy<'tcx &self, _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { - Ok(self.into()) + Ok(self.clone().into()) } } @@ -442,7 +442,7 @@ where #[instrument(skip(self), level = "debug")] pub fn deref_operand( &self, - src: &OpTy<'tcx, M::Provenance>, + src: &impl Readable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { let val = self.read_immediate(src)?; trace!("deref to {} on {:?}", val.layout.ty, *val); @@ -766,7 +766,7 @@ where #[instrument(skip(self), level = "debug")] pub fn copy_op( &mut self, - src: &OpTy<'tcx, M::Provenance>, + src: &impl Readable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, allow_transmute: bool, ) -> InterpResult<'tcx> { @@ -787,19 +787,19 @@ where #[instrument(skip(self), level = "debug")] fn copy_op_no_validate( &mut self, - src: &OpTy<'tcx, M::Provenance>, + src: &impl Readable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, allow_transmute: bool, ) -> InterpResult<'tcx> { // We do NOT compare the types for equality, because well-typed code can // actually "transmute" `&mut T` to `&T` in an assignment without a cast. let layout_compat = - mir_assign_valid_types(*self.tcx, self.param_env, src.layout, dest.layout()); + mir_assign_valid_types(*self.tcx, self.param_env, src.layout(), dest.layout()); if !allow_transmute && !layout_compat { span_bug!( self.cur_span(), "type mismatch when copying!\nsrc: {:?},\ndest: {:?}", - src.layout.ty, + src.layout().ty, dest.layout().ty, ); } @@ -813,13 +813,13 @@ where // actually sized, due to a trivially false where-clause // predicate like `where Self: Sized` with `Self = dyn Trait`. // See #102553 for an example of such a predicate. - if src.layout.is_unsized() { - throw_inval!(SizeOfUnsizedType(src.layout.ty)); + if src.layout().is_unsized() { + throw_inval!(SizeOfUnsizedType(src.layout().ty)); } if dest.layout().is_unsized() { throw_inval!(SizeOfUnsizedType(dest.layout().ty)); } - assert_eq!(src.layout.size, dest.layout().size); + assert_eq!(src.layout().size, dest.layout().size); // Yay, we got a value that we can write directly. return if layout_compat { self.write_immediate_no_validate(*src_val, dest) @@ -831,7 +831,7 @@ where let dest_mem = dest.force_mplace(self)?; self.write_immediate_to_mplace_no_validate( *src_val, - src.layout, + src.layout(), dest_mem.align, *dest_mem, ) diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 01b945afda636..ac07c25763bac 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -494,7 +494,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { trace!("assertion on {:?} should be {:?}", value, expected); let expected = Scalar::from_bool(expected); - let value_const = self.use_ecx(location, |this| this.ecx.read_scalar(&value))?; + let value_const = self.use_ecx(location, |this| this.ecx.read_scalar(value))?; if expected != value_const { // Poison all places this operand references so that further code @@ -664,7 +664,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { } TerminatorKind::SwitchInt { ref discr, ref targets } => { if let Some(ref value) = self.eval_operand(&discr, location) - && let Some(value_const) = self.use_ecx(location, |this| this.ecx.read_scalar(&value)) + && let Some(value_const) = self.use_ecx(location, |this| this.ecx.read_scalar(value)) && let Ok(constant) = value_const.try_to_int() && let Ok(constant) = constant.to_bits(constant.size()) { diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 4db55abd2323f..37125337d6f0e 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -472,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { // This is fine with StackedBorrow and race checks because they don't concern metadata on // the *value* (including the associated provenance if this is an AtomicPtr) at this location. // Only metadata on the location itself is used. - let scalar = this.allow_data_races_ref(move |this| this.read_scalar(&place.into()))?; + let scalar = this.allow_data_races_ref(move |this| this.read_scalar(place))?; this.validate_overlapping_atomic(place)?; this.buffered_atomic_read(place, atomic, scalar, || { this.validate_atomic_load(place, atomic) @@ -513,7 +513,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { this.atomic_access_check(place)?; this.validate_overlapping_atomic(place)?; - let old = this.allow_data_races_mut(|this| this.read_immediate(&place.into()))?; + let old = this.allow_data_races_mut(|this| this.read_immediate(place))?; // Atomics wrap around on overflow. let val = this.binary_op(op, &old, rhs)?; @@ -538,7 +538,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { this.atomic_access_check(place)?; this.validate_overlapping_atomic(place)?; - let old = this.allow_data_races_mut(|this| this.read_scalar(&place.into()))?; + let old = this.allow_data_races_mut(|this| this.read_scalar(place))?; this.allow_data_races_mut(|this| this.write_scalar(new, place))?; this.validate_atomic_rmw(place, atomic)?; @@ -560,7 +560,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { this.atomic_access_check(place)?; this.validate_overlapping_atomic(place)?; - let old = this.allow_data_races_mut(|this| this.read_immediate(&place.into()))?; + let old = this.allow_data_races_mut(|this| this.read_immediate(place))?; let lt = this.binary_op(mir::BinOp::Lt, &old, &rhs)?.to_scalar().to_bool()?; let new_val = if min { @@ -603,7 +603,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { // to read with the failure ordering and if successful then try again with the success // read ordering and write in the success case. // Read as immediate for the sake of `binary_op()` - let old = this.allow_data_races_mut(|this| this.read_immediate(&(place.into())))?; + let old = this.allow_data_races_mut(|this| this.read_immediate(place))?; // `binary_op` will bail if either of them is not a scalar. let eq = this.binary_op(mir::BinOp::Eq, &old, expect_old)?; // If the operation would succeed, but is "weak", fail some portion diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 36c43053648cb..b761a6cf47559 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -246,7 +246,7 @@ impl MainThreadState { this.machine.main_fn_ret_place.unwrap().ptr, this.machine.layouts.isize, ); - let exit_code = this.read_target_isize(&ret_place.into())?; + let exit_code = this.read_target_isize(&ret_place)?; // Need to call this ourselves since we are not going to return to the scheduler // loop, and we want the main thread TLS to not show up as memory leaks. this.terminate_active_thread()?; diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 7e9f9c05c0cdb..928bee48356ae 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -166,7 +166,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let const_val = this.eval_global(cid, None).unwrap_or_else(|err| { panic!("failed to evaluate required Rust item: {path:?}\n{err:?}") }); - this.read_scalar(&const_val.into()) + this.read_scalar(&const_val) .unwrap_or_else(|err| panic!("failed to read required Rust item: {path:?}\n{err:?}")) } @@ -623,7 +623,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); let errno_place = this.last_error_place()?; - this.read_scalar(&errno_place.into()) + this.read_scalar(&errno_place) } /// This function tries to produce the most similar OS error from the `std::io::ErrorKind` @@ -772,7 +772,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_ref(); let value_place = this.deref_operand_and_offset(op, offset, base_layout, value_layout)?; - this.read_scalar(&value_place.into()) + this.read_scalar(&value_place) } fn write_scalar_at_offset( @@ -797,10 +797,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Option> { let this = self.eval_context_mut(); let seconds_place = this.project_field(tp, 0)?; - let seconds_scalar = this.read_scalar(&seconds_place.into())?; + let seconds_scalar = this.read_scalar(&seconds_place)?; let seconds = seconds_scalar.to_target_isize(this)?; let nanoseconds_place = this.project_field(tp, 1)?; - let nanoseconds_scalar = this.read_scalar(&nanoseconds_place.into())?; + let nanoseconds_scalar = this.read_scalar(&nanoseconds_place)?; let nanoseconds = nanoseconds_scalar.to_target_isize(this)?; Ok(try { diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 8c72c4d3a4212..3d1dfb426cdc4 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -88,7 +88,7 @@ impl<'tcx> EnvVars<'tcx> { } // Deallocate environ var list. let environ = ecx.machine.env_vars.environ.unwrap(); - let old_vars_ptr = ecx.read_pointer(&environ.into())?; + let old_vars_ptr = ecx.read_pointer(&environ)?; ecx.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?; Ok(()) } @@ -432,7 +432,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); // Deallocate the old environ list, if any. if let Some(environ) = this.machine.env_vars.environ { - let old_vars_ptr = this.read_pointer(&environ.into())?; + let old_vars_ptr = this.read_pointer(&environ)?; this.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?; } else { // No `environ` allocated yet, let's do that. diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index cb8e7c1471036..26f0a6606573a 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -97,7 +97,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "volatile_load" => { let [place] = check_arg_count(args)?; let place = this.deref_operand(place)?; - this.copy_op(&place.into(), dest, /*allow_transmute*/ false)?; + this.copy_op(&place, dest, /*allow_transmute*/ false)?; } "volatile_store" => { let [place, dest] = check_arg_count(args)?; diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index ed997bad1ef4c..103feae4ae7ae 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -57,7 +57,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; for i in 0..dest_len { - let op = this.read_immediate(&this.project_index(&op, i)?.into())?; + let op = this.read_immediate(&this.project_index(&op, i)?)?; let dest = this.project_index(&dest, i)?; let val = match which { Op::MirOp(mir_op) => this.unary_op(mir_op, &op)?.to_scalar(), @@ -172,8 +172,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; for i in 0..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?.into())?; - let right = this.read_immediate(&this.project_index(&right, i)?.into())?; + let left = this.read_immediate(&this.project_index(&left, i)?)?; + let right = this.read_immediate(&this.project_index(&right, i)?)?; let dest = this.project_index(&dest, i)?; let val = match which { Op::MirOp(mir_op) => { @@ -232,9 +232,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(dest_len, c_len); for i in 0..dest_len { - let a = this.read_scalar(&this.project_index(&a, i)?.into())?; - let b = this.read_scalar(&this.project_index(&b, i)?.into())?; - let c = this.read_scalar(&this.project_index(&c, i)?.into())?; + let a = this.read_scalar(&this.project_index(&a, i)?)?; + let b = this.read_scalar(&this.project_index(&b, i)?)?; + let c = this.read_scalar(&this.project_index(&c, i)?)?; let dest = this.project_index(&dest, i)?; // Works for f32 and f64. @@ -295,13 +295,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; // Initialize with first lane, then proceed with the rest. - let mut res = this.read_immediate(&this.project_index(&op, 0)?.into())?; + let mut res = this.read_immediate(&this.project_index(&op, 0)?)?; if matches!(which, Op::MirOpBool(_)) { // Convert to `bool` scalar. res = imm_from_bool(simd_element_to_bool(res)?); } for i in 1..op_len { - let op = this.read_immediate(&this.project_index(&op, i)?.into())?; + let op = this.read_immediate(&this.project_index(&op, i)?)?; res = match which { Op::MirOp(mir_op) => { this.binary_op(mir_op, &res, &op)? @@ -355,7 +355,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let mut res = init; for i in 0..op_len { - let op = this.read_immediate(&this.project_index(&op, i)?.into())?; + let op = this.read_immediate(&this.project_index(&op, i)?)?; res = this.binary_op(mir_op, &res, &op)?; } this.write_immediate(*res, dest)?; @@ -372,9 +372,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(dest_len, no_len); for i in 0..dest_len { - let mask = this.read_immediate(&this.project_index(&mask, i)?.into())?; - let yes = this.read_immediate(&this.project_index(&yes, i)?.into())?; - let no = this.read_immediate(&this.project_index(&no, i)?.into())?; + let mask = this.read_immediate(&this.project_index(&mask, i)?)?; + let yes = this.read_immediate(&this.project_index(&yes, i)?)?; + let no = this.read_immediate(&this.project_index(&no, i)?)?; let dest = this.project_index(&dest, i)?; let val = if simd_element_to_bool(mask)? { yes } else { no }; @@ -403,8 +403,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { & 1u64 .checked_shl(simd_bitmask_index(i, dest_len, this.data_layout().endian)) .unwrap(); - let yes = this.read_immediate(&this.project_index(&yes, i.into())?.into())?; - let no = this.read_immediate(&this.project_index(&no, i.into())?.into())?; + let yes = this.read_immediate(&this.project_index(&yes, i.into())?)?; + let no = this.read_immediate(&this.project_index(&no, i.into())?)?; let dest = this.project_index(&dest, i.into())?; let val = if mask != 0 { yes } else { no }; @@ -435,7 +435,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let from_exposed_cast = intrinsic_name == "from_exposed_addr"; for i in 0..dest_len { - let op = this.read_immediate(&this.project_index(&op, i)?.into())?; + let op = this.read_immediate(&this.project_index(&op, i)?)?; let dest = this.project_index(&dest, i)?; let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) { @@ -503,10 +503,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let dest = this.project_index(&dest, i)?; let val = if src_index < left_len { - this.read_immediate(&this.project_index(&left, src_index)?.into())? + this.read_immediate(&this.project_index(&left, src_index)?)? } else if src_index < left_len.checked_add(right_len).unwrap() { let right_idx = src_index.checked_sub(left_len).unwrap(); - this.read_immediate(&this.project_index(&right, right_idx)?.into())? + this.read_immediate(&this.project_index(&right, right_idx)?)? } else { span_bug!( this.cur_span(), @@ -528,14 +528,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(dest_len, mask_len); for i in 0..dest_len { - let passthru = this.read_immediate(&this.project_index(&passthru, i)?.into())?; - let ptr = this.read_immediate(&this.project_index(&ptrs, i)?.into())?; - let mask = this.read_immediate(&this.project_index(&mask, i)?.into())?; + let passthru = this.read_immediate(&this.project_index(&passthru, i)?)?; + let ptr = this.read_immediate(&this.project_index(&ptrs, i)?)?; + let mask = this.read_immediate(&this.project_index(&mask, i)?)?; let dest = this.project_index(&dest, i)?; let val = if simd_element_to_bool(mask)? { - let place = this.deref_operand(&ptr.into())?; - this.read_immediate(&place.into())? + let place = this.deref_operand(&ptr)?; + this.read_immediate(&place)? } else { passthru }; @@ -552,12 +552,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(ptrs_len, mask_len); for i in 0..ptrs_len { - let value = this.read_immediate(&this.project_index(&value, i)?.into())?; - let ptr = this.read_immediate(&this.project_index(&ptrs, i)?.into())?; - let mask = this.read_immediate(&this.project_index(&mask, i)?.into())?; + let value = this.read_immediate(&this.project_index(&value, i)?)?; + let ptr = this.read_immediate(&this.project_index(&ptrs, i)?)?; + let mask = this.read_immediate(&this.project_index(&mask, i)?)?; if simd_element_to_bool(mask)? { - let place = this.deref_operand(&ptr.into())?; + let place = this.deref_operand(&ptr)?; this.write_immediate(*value, &place)?; } } @@ -578,7 +578,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let mut res = 0u64; for i in 0..op_len { - let op = this.read_immediate(&this.project_index(&op, i.into())?.into())?; + let op = this.read_immediate(&this.project_index(&op, i.into())?)?; if simd_element_to_bool(op)? { res |= 1u64 .checked_shl(simd_bitmask_index(i, op_len, this.data_layout().endian)) diff --git a/src/tools/miri/src/shims/unix/linux/fd.rs b/src/tools/miri/src/shims/unix/linux/fd.rs index 2855157f49dd1..92966319f19ca 100644 --- a/src/tools/miri/src/shims/unix/linux/fd.rs +++ b/src/tools/miri/src/shims/unix/linux/fd.rs @@ -74,9 +74,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let event = this.deref_operand_as(event, this.libc_ty_layout("epoll_event"))?; let events = this.project_field(&event, 0)?; - let events = this.read_scalar(&events.into())?.to_u32()?; + let events = this.read_scalar(&events)?.to_u32()?; let data = this.project_field(&event, 1)?; - let data = this.read_scalar(&data.into())?; + let data = this.read_scalar(&data)?; let event = EpollEvent { events, data }; if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) { diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index f42f3f90684a8..7ab1b3dfdb210 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -133,7 +133,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let (written, size_needed) = this.write_path_to_c_str( &path, buf_ptr, - this.read_scalar(&bufsize.into())?.to_u32()?.into(), + this.read_scalar(&bufsize)?.to_u32()?.into(), )?; if written { diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 172312e331a0b..5d5cf73797f32 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let layout = this.machine.layouts.uint(size).unwrap(); let futex_val = this .read_scalar_atomic(&MPlaceTy::from_aligned_ptr(ptr, layout), AtomicReadOrd::Relaxed)?; - let compare_val = this.read_scalar(&MPlaceTy::from_aligned_ptr(compare, layout).into())?; + let compare_val = this.read_scalar(&MPlaceTy::from_aligned_ptr(compare, layout))?; if futex_val == compare_val { // If the values are the same, we have to block. From da3f0d0eb7ced3d4967dcac01ddd2edef8f43b85 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Jul 2023 22:35:07 +0200 Subject: [PATCH 3/4] make MPlaceTy non-Copy --- .../rustc_const_eval/src/const_eval/eval_queries.rs | 4 ++-- compiler/rustc_const_eval/src/const_eval/valtrees.rs | 8 ++++---- compiler/rustc_const_eval/src/interpret/intern.rs | 4 ++-- compiler/rustc_const_eval/src/interpret/operand.rs | 2 +- compiler/rustc_const_eval/src/interpret/place.rs | 6 +++--- compiler/rustc_const_eval/src/interpret/terminator.rs | 2 +- compiler/rustc_const_eval/src/interpret/validity.rs | 6 +++--- src/tools/miri/src/helpers.rs | 8 ++++---- src/tools/miri/src/machine.rs | 4 ++-- src/tools/miri/src/shims/env.rs | 10 +++++----- src/tools/miri/src/shims/unix/macos/foreign_items.rs | 2 +- 11 files changed, 28 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index b21cb984de67f..55d719d2703ae 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -58,7 +58,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.push_stack_frame( cid.instance, body, - &ret.into(), + &ret.clone().into(), StackPopCleanup::Root { cleanup: false }, )?; @@ -356,7 +356,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( // Since evaluation had no errors, validate the resulting constant. // This is a separate `try` block to provide more targeted error reporting. let validation: Result<_, InterpErrorInfo<'_>> = try { - let mut ref_tracking = RefTracking::new(mplace); + let mut ref_tracking = RefTracking::new(mplace.clone()); let mut inner = false; while let Some((mplace, path)) = ref_tracking.todo.pop() { let mode = match tcx.static_mutability(cid.instance.def_id()) { diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index be5eb1558cf12..8f68f83775969 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -21,7 +21,7 @@ fn branches<'tcx>( ) -> ValTreeCreationResult<'tcx> { let place = match variant { Some(variant) => ecx.project_downcast(place, variant).unwrap(), - None => *place, + None => place.clone(), }; let variant = variant.map(|variant| Some(ty::ValTree::Leaf(ScalarInt::from(variant.as_u32())))); debug!(?place, ?variant); @@ -290,7 +290,7 @@ pub fn valtree_to_const_value<'tcx>( debug!(?place); valtree_into_mplace(&mut ecx, &mut place, valtree); - dump_place(&ecx, place.into()); + dump_place(&ecx, place.clone().into()); intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap(); match ty.kind() { @@ -352,7 +352,7 @@ fn valtree_into_mplace<'tcx>( debug!(?pointee_place); valtree_into_mplace(ecx, &mut pointee_place, valtree); - dump_place(ecx, pointee_place.into()); + dump_place(ecx, pointee_place.clone().into()); intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap(); let imm = match inner_ty.kind() { @@ -389,7 +389,7 @@ fn valtree_into_mplace<'tcx>( Some(variant_idx), ) } - _ => (*place, branches, None), + _ => (place.clone(), branches, None), }; debug!(?place_adjusted, ?branches); diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index e1088e72eb6d5..910c3ca5d0a97 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -358,7 +358,7 @@ pub fn intern_const_alloc_recursive< Some(ret.layout.ty), ); - ref_tracking.track((*ret, base_intern_mode), || ()); + ref_tracking.track((ret.clone(), base_intern_mode), || ()); while let Some(((mplace, mode), _)) = ref_tracking.todo.pop() { let res = InternVisitor { @@ -464,7 +464,7 @@ impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>> ) -> InterpResult<'tcx, ()>, ) -> InterpResult<'tcx, ConstAllocation<'tcx>> { let dest = self.allocate(layout, MemoryKind::Stack)?; - f(self, &dest.into())?; + f(self, &dest.clone().into())?; let mut alloc = self.memory.alloc_map.remove(&dest.ptr.provenance.unwrap()).unwrap().1; alloc.mutability = Mutability::Not; Ok(self.tcx.mk_const_alloc(alloc)) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 32a2f64832159..d1427b09632d8 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -476,7 +476,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? { Right(val) } else { - Left(*mplace) + Left(mplace.clone()) } } Right(val) => Right(val), diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 306ad20c88348..96a960118ce17 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -81,7 +81,7 @@ pub struct MemPlace { } /// A MemPlace with its layout. Constructing it is only possible in this module. -#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] +#[derive(Clone, Hash, Eq, PartialEq, Debug)] pub struct MPlaceTy<'tcx, Prov: Provenance = AllocId> { mplace: MemPlace, pub layout: TyAndLayout<'tcx>, @@ -452,7 +452,7 @@ where } let mplace = self.ref_to_mplace(&val)?; - self.check_mplace(mplace)?; + self.check_mplace(&mplace)?; Ok(mplace) } @@ -483,7 +483,7 @@ where } /// Check if this mplace is dereferenceable and sufficiently aligned. - pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> 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)); diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index f934cca2517b9..d0191ea978a46 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -634,7 +634,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Ensure the return place is aligned and dereferenceable, and protect it for // in-place return value passing. if let Either::Left(mplace) = destination.as_mplace_or_local() { - self.check_mplace(mplace)?; + self.check_mplace(&mplace)?; } else { // Nothing to do for locals, they are always properly allocated and aligned. } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index a82c98e720578..4fd5fd13c3cf4 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -136,19 +136,19 @@ pub struct RefTracking { pub todo: Vec<(T, PATH)>, } -impl RefTracking { +impl RefTracking { pub fn empty() -> Self { RefTracking { seen: FxHashSet::default(), todo: vec![] } } pub fn new(op: T) -> Self { let mut ref_tracking_for_consts = - RefTracking { seen: FxHashSet::default(), todo: vec![(op, PATH::default())] }; + RefTracking { seen: FxHashSet::default(), todo: vec![(op.clone(), PATH::default())] }; ref_tracking_for_consts.seen.insert(op); ref_tracking_for_consts } pub fn track(&mut self, op: T, path: impl FnOnce() -> PATH) { - if self.seen.insert(op) { + if self.seen.insert(op.clone()) { trace!("Recursing below ptr {:#?}", op); let path = path(); // Remember to come back to this later. diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 928bee48356ae..d41bcc978b0c1 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -600,14 +600,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// necessary. fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { let this = self.eval_context_mut(); - if let Some(errno_place) = this.active_thread_ref().last_error { - Ok(errno_place) + if let Some(errno_place) = this.active_thread_ref().last_error.as_ref() { + Ok(errno_place.clone()) } else { // Allocate new place, set initial value to 0. let errno_layout = this.machine.layouts.u32; let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into())?; this.write_scalar(Scalar::from_u32(0), &errno_place)?; - this.active_thread_mut().last_error = Some(errno_place); + this.active_thread_mut().last_error = Some(errno_place.clone()); Ok(errno_place) } } @@ -725,7 +725,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let mplace = MPlaceTy::from_aligned_ptr(ptr, layout); - this.check_mplace(mplace)?; + this.check_mplace(&mplace)?; Ok(mplace) } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 8d24d9748bf91..0c9c072b0511d 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -668,7 +668,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { Self::add_extern_static( this, "environ", - this.machine.env_vars.environ.unwrap().ptr, + this.machine.env_vars.environ.as_ref().unwrap().ptr, ); // A couple zero-initialized pointer-sized extern statics. // Most of them are for weak symbols, which we all set to null (indicating that the @@ -685,7 +685,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { Self::add_extern_static( this, "environ", - this.machine.env_vars.environ.unwrap().ptr, + this.machine.env_vars.environ.as_ref().unwrap().ptr, ); } "android" => { diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 3d1dfb426cdc4..3694ea51da6c6 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -87,8 +87,8 @@ impl<'tcx> EnvVars<'tcx> { ecx.deallocate_ptr(ptr, None, MiriMemoryKind::Runtime.into())?; } // Deallocate environ var list. - let environ = ecx.machine.env_vars.environ.unwrap(); - let old_vars_ptr = ecx.read_pointer(&environ)?; + let environ = ecx.machine.env_vars.environ.as_ref().unwrap(); + let old_vars_ptr = ecx.read_pointer(environ)?; ecx.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?; Ok(()) } @@ -431,8 +431,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn update_environ(&mut self) -> InterpResult<'tcx> { let this = self.eval_context_mut(); // Deallocate the old environ list, if any. - if let Some(environ) = this.machine.env_vars.environ { - let old_vars_ptr = this.read_pointer(&environ)?; + if let Some(environ) = this.machine.env_vars.environ.as_ref() { + let old_vars_ptr = this.read_pointer(environ)?; this.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?; } else { // No `environ` allocated yet, let's do that. @@ -459,7 +459,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let place = this.project_field(&vars_place, idx)?; this.write_pointer(var, &place)?; } - this.write_pointer(vars_place.ptr, &this.machine.env_vars.environ.unwrap())?; + this.write_pointer(vars_place.ptr, &this.machine.env_vars.environ.clone().unwrap())?; Ok(()) } diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 7ab1b3dfdb210..3673ca5aee367 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -86,7 +86,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "_NSGetEnviron" => { let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.write_pointer( - this.machine.env_vars.environ.expect("machine must be initialized").ptr, + this.machine.env_vars.environ.as_ref().expect("machine must be initialized").ptr, dest, )?; } From 571e8ce777447a542dfefd0151b17503a380176f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 26 Jul 2023 11:14:27 +0200 Subject: [PATCH 4/4] valtree: a bit of cleanup --- .../src/const_eval/valtrees.rs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 8f68f83775969..744dd114ca713 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -5,7 +5,7 @@ use crate::const_eval::CanAccessStatics; use crate::interpret::MPlaceTy; use crate::interpret::{ intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta, - MemoryKind, PlaceTy, Projectable, Scalar, + MemoryKind, Place, Projectable, Scalar, }; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; @@ -280,7 +280,7 @@ pub fn valtree_to_const_value<'tcx>( ), }, ty::Ref(_, _, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => { - let mut place = match ty.kind() { + let place = match ty.kind() { ty::Ref(_, inner_ty, _) => { // Need to create a place for the pointee to fill for Refs create_pointee_place(&mut ecx, *inner_ty, valtree) @@ -289,8 +289,8 @@ pub fn valtree_to_const_value<'tcx>( }; debug!(?place); - valtree_into_mplace(&mut ecx, &mut place, valtree); - dump_place(&ecx, place.clone().into()); + valtree_into_mplace(&mut ecx, &place, valtree); + dump_place(&ecx, &place); intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap(); match ty.kind() { @@ -329,7 +329,7 @@ pub fn valtree_to_const_value<'tcx>( #[instrument(skip(ecx), level = "debug")] fn valtree_into_mplace<'tcx>( ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, - place: &mut MPlaceTy<'tcx>, + place: &MPlaceTy<'tcx>, valtree: ty::ValTree<'tcx>, ) { // This will match on valtree and write the value(s) corresponding to the ValTree @@ -348,11 +348,11 @@ fn valtree_into_mplace<'tcx>( ecx.write_immediate(Immediate::Scalar(scalar_int.into()), place).unwrap(); } ty::Ref(_, inner_ty, _) => { - let mut pointee_place = create_pointee_place(ecx, *inner_ty, valtree); + let pointee_place = create_pointee_place(ecx, *inner_ty, valtree); debug!(?pointee_place); - valtree_into_mplace(ecx, &mut pointee_place, valtree); - dump_place(ecx, pointee_place.clone().into()); + valtree_into_mplace(ecx, &pointee_place, valtree); + dump_place(ecx, &pointee_place); intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap(); let imm = match inner_ty.kind() { @@ -398,7 +398,7 @@ fn valtree_into_mplace<'tcx>( for (i, inner_valtree) in branches.iter().enumerate() { debug!(?i, ?inner_valtree); - let mut place_inner = match ty.kind() { + let place_inner = match ty.kind() { ty::Str | ty::Slice(_) => ecx.project_index(place, i as u64).unwrap(), _ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) && i == branches.len() - 1 => @@ -443,12 +443,12 @@ fn valtree_into_mplace<'tcx>( }; debug!(?place_inner); - valtree_into_mplace(ecx, &mut place_inner, *inner_valtree); - dump_place(&ecx, place_inner.into()); + valtree_into_mplace(ecx, &place_inner, *inner_valtree); + dump_place(&ecx, &place_inner); } debug!("dump of place_adjusted:"); - dump_place(ecx, place_adjusted.into()); + dump_place(ecx, &place_adjusted); if let Some(variant_idx) = variant_idx { // don't forget filling the place with the discriminant of the enum @@ -456,12 +456,12 @@ fn valtree_into_mplace<'tcx>( } debug!("dump of place after writing discriminant:"); - dump_place(ecx, place.clone().into()); + dump_place(ecx, place); } _ => bug!("shouldn't have created a ValTree for {:?}", ty), } } -fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: PlaceTy<'tcx>) { - trace!("{:?}", ecx.dump_place(*place)); +fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>) { + trace!("{:?}", ecx.dump_place(Place::Ptr(**place))); }