@@ -26,6 +26,7 @@ pub enum MemPlaceMeta<Prov: Provenance = AllocId> {
26
26
}
27
27
28
28
impl < Prov : Provenance > MemPlaceMeta < Prov > {
29
+ #[ cfg_attr( debug_assertions, track_caller) ] // only in debug builds due to perf (see #98980)
29
30
pub fn unwrap_meta ( self ) -> Scalar < Prov > {
30
31
match self {
31
32
Self :: Meta ( s) => s,
@@ -147,12 +148,16 @@ impl<Prov: Provenance> MemPlace<Prov> {
147
148
}
148
149
149
150
#[ inline]
150
- pub fn offset_with_meta < ' tcx > (
151
+ pub ( super ) fn offset_with_meta < ' tcx > (
151
152
self ,
152
153
offset : Size ,
153
154
meta : MemPlaceMeta < Prov > ,
154
155
cx : & impl HasDataLayout ,
155
156
) -> 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
+ ) ;
156
161
Ok ( MemPlace { ptr : self . ptr . offset ( offset, cx) ?, meta } )
157
162
}
158
163
}
@@ -182,8 +187,11 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
182
187
MPlaceTy { mplace : MemPlace { ptr, meta : MemPlaceMeta :: None } , layout, align }
183
188
}
184
189
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!
185
193
#[ inline]
186
- pub fn offset_with_meta (
194
+ pub ( crate ) fn offset_with_meta (
187
195
& self ,
188
196
offset : Size ,
189
197
meta : MemPlaceMeta < Prov > ,
@@ -197,6 +205,9 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
197
205
} )
198
206
}
199
207
208
+ /// Offset the place in memory.
209
+ ///
210
+ /// This can go wrong very easily if you give the wrong layout for the new place!
200
211
pub fn offset (
201
212
& self ,
202
213
offset : Size ,
@@ -241,14 +252,6 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
241
252
}
242
253
}
243
254
}
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
- }
252
255
}
253
256
254
257
// These are defined here because they produce a place.
@@ -266,7 +269,12 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
266
269
#[ inline( always) ]
267
270
#[ cfg_attr( debug_assertions, track_caller) ] // only in debug builds due to perf (see #98980)
268
271
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
+ } )
270
278
}
271
279
}
272
280
@@ -283,7 +291,12 @@ impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> {
283
291
#[ inline( always) ]
284
292
#[ cfg_attr( debug_assertions, track_caller) ] // only in debug builds due to perf (see #98980)
285
293
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
+ } )
287
300
}
288
301
}
289
302
@@ -807,11 +820,16 @@ where
807
820
}
808
821
809
822
/// Turn a place with a `dyn Trait` type into a place with the actual dynamic type.
823
+ /// Aso returns the vtable.
810
824
pub ( super ) fn unpack_dyn_trait (
811
825
& self ,
812
826
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 ) ?;
815
833
let ( ty, _) = self . get_ptr_vtable ( vtable) ?;
816
834
let layout = self . layout_of ( ty) ?;
817
835
@@ -820,7 +838,26 @@ where
820
838
layout,
821
839
align : layout. align . abi ,
822
840
} ;
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) )
824
861
}
825
862
}
826
863
0 commit comments