@@ -26,6 +26,7 @@ pub enum MemPlaceMeta<Prov: Provenance = AllocId> {
2626}
2727
2828impl < Prov : Provenance > MemPlaceMeta < Prov > {
29+ #[ cfg_attr( debug_assertions, track_caller) ] // only in debug builds due to perf (see #98980)
2930 pub fn unwrap_meta ( self ) -> Scalar < Prov > {
3031 match self {
3132 Self :: Meta ( s) => s,
@@ -147,12 +148,16 @@ impl<Prov: Provenance> MemPlace<Prov> {
147148 }
148149
149150 #[ inline]
150- pub fn offset_with_meta < ' tcx > (
151+ pub ( super ) fn offset_with_meta < ' tcx > (
151152 self ,
152153 offset : Size ,
153154 meta : MemPlaceMeta < Prov > ,
154155 cx : & impl HasDataLayout ,
155156 ) -> InterpResult < ' tcx , Self > {
157+ debug_assert ! (
158+ !meta. has_meta( ) || self . meta. has_meta( ) ,
159+ "cannot use `offset_with_meta` to add metadata to a place"
160+ ) ;
156161 Ok ( MemPlace { ptr : self . ptr . offset ( offset, cx) ?, meta } )
157162 }
158163}
@@ -182,8 +187,11 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
182187 MPlaceTy { mplace : MemPlace { ptr, meta : MemPlaceMeta :: None } , layout, align }
183188 }
184189
190+ /// Offset the place in memory and change its metadata.
191+ ///
192+ /// This can go wrong very easily if you give the wrong layout for the new place!
185193 #[ inline]
186- pub fn offset_with_meta (
194+ pub ( crate ) fn offset_with_meta (
187195 & self ,
188196 offset : Size ,
189197 meta : MemPlaceMeta < Prov > ,
@@ -197,6 +205,9 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
197205 } )
198206 }
199207
208+ /// Offset the place in memory.
209+ ///
210+ /// This can go wrong very easily if you give the wrong layout for the new place!
200211 pub fn offset (
201212 & self ,
202213 offset : Size ,
@@ -241,14 +252,6 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
241252 }
242253 }
243254 }
244-
245- #[ inline]
246- pub ( super ) fn vtable ( & self ) -> Scalar < Prov > {
247- match self . layout . ty . kind ( ) {
248- ty:: Dynamic ( ..) => self . mplace . meta . unwrap_meta ( ) ,
249- _ => bug ! ( "vtable not supported on type {:?}" , self . layout. ty) ,
250- }
251- }
252255}
253256
254257// These are defined here because they produce a place.
@@ -266,7 +269,12 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
266269 #[ inline( always) ]
267270 #[ cfg_attr( debug_assertions, track_caller) ] // only in debug builds due to perf (see #98980)
268271 pub fn assert_mem_place ( & self ) -> MPlaceTy < ' tcx , Prov > {
269- self . as_mplace_or_imm ( ) . left ( ) . unwrap ( )
272+ self . as_mplace_or_imm ( ) . left ( ) . unwrap_or_else ( || {
273+ bug ! (
274+ "OpTy of type {} was immediate when it was expected to be an MPlace" ,
275+ self . layout. ty
276+ )
277+ } )
270278 }
271279}
272280
@@ -283,7 +291,12 @@ impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> {
283291 #[ inline( always) ]
284292 #[ cfg_attr( debug_assertions, track_caller) ] // only in debug builds due to perf (see #98980)
285293 pub fn assert_mem_place ( & self ) -> MPlaceTy < ' tcx , Prov > {
286- self . as_mplace_or_local ( ) . left ( ) . unwrap ( )
294+ self . as_mplace_or_local ( ) . left ( ) . unwrap_or_else ( || {
295+ bug ! (
296+ "PlaceTy of type {} was a local when it was expected to be an MPlace" ,
297+ self . layout. ty
298+ )
299+ } )
287300 }
288301}
289302
@@ -807,11 +820,16 @@ where
807820 }
808821
809822 /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type.
823+ /// Aso returns the vtable.
810824 pub ( super ) fn unpack_dyn_trait (
811825 & self ,
812826 mplace : & MPlaceTy < ' tcx , M :: Provenance > ,
813- ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , M :: Provenance > > {
814- let vtable = mplace. vtable ( ) . to_pointer ( self ) ?; // also sanity checks the type
827+ ) -> InterpResult < ' tcx , ( MPlaceTy < ' tcx , M :: Provenance > , Pointer < Option < M :: Provenance > > ) > {
828+ assert ! (
829+ matches!( mplace. layout. ty. kind( ) , ty:: Dynamic ( _, _, ty:: Dyn ) ) ,
830+ "`unpack_dyn_trait` only makes sense on `dyn*` types"
831+ ) ;
832+ let vtable = mplace. meta . unwrap_meta ( ) . to_pointer ( self ) ?;
815833 let ( ty, _) = self . get_ptr_vtable ( vtable) ?;
816834 let layout = self . layout_of ( ty) ?;
817835
@@ -820,7 +838,26 @@ where
820838 layout,
821839 align : layout. align . abi ,
822840 } ;
823- Ok ( mplace)
841+ Ok ( ( mplace, vtable) )
842+ }
843+
844+ /// Turn an operand with a `dyn* Trait` type into an operand with the actual dynamic type.
845+ /// Aso returns the vtable.
846+ pub ( super ) fn unpack_dyn_star (
847+ & self ,
848+ op : & OpTy < ' tcx , M :: Provenance > ,
849+ ) -> InterpResult < ' tcx , ( OpTy < ' tcx , M :: Provenance > , Pointer < Option < M :: Provenance > > ) > {
850+ assert ! (
851+ matches!( op. layout. ty. kind( ) , ty:: Dynamic ( _, _, ty:: DynStar ) ) ,
852+ "`unpack_dyn_star` only makes sense on `dyn*` types"
853+ ) ;
854+ let data = self . operand_field ( & op, 0 ) ?;
855+ let vtable = self . operand_field ( & op, 1 ) ?;
856+ let vtable = self . read_pointer ( & vtable) ?;
857+ let ( ty, _) = self . get_ptr_vtable ( vtable) ?;
858+ let layout = self . layout_of ( ty) ?;
859+ let data = data. transmute ( layout) ;
860+ Ok ( ( data, vtable) )
824861 }
825862}
826863
0 commit comments