@@ -25,12 +25,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
2525 // FIXME: In which cases should we trigger UB when the source is uninit?
2626 match cast_kind {
2727 Pointer ( PointerCast :: Unsize ) => {
28- assert_eq ! (
29- cast_ty, dest. layout. ty,
30- "mismatch of cast type {} and place type {}" ,
31- cast_ty, dest. layout. ty
32- ) ;
33- self . unsize_into ( src, dest) ?;
28+ let cast_ty = self . layout_of ( cast_ty) ?;
29+ self . unsize_into ( src, cast_ty, dest) ?;
3430 }
3531
3632 Misc => {
@@ -266,11 +262,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
266262 dest : PlaceTy < ' tcx , M :: PointerTag > ,
267263 // The pointee types
268264 source_ty : Ty < ' tcx > ,
269- dest_ty : Ty < ' tcx > ,
265+ cast_ty : Ty < ' tcx > ,
270266 ) -> InterpResult < ' tcx > {
271267 // A<Struct> -> A<Trait> conversion
272268 let ( src_pointee_ty, dest_pointee_ty) =
273- self . tcx . struct_lockstep_tails_erasing_lifetimes ( source_ty, dest_ty , self . param_env ) ;
269+ self . tcx . struct_lockstep_tails_erasing_lifetimes ( source_ty, cast_ty , self . param_env ) ;
274270
275271 match ( & src_pointee_ty. kind , & dest_pointee_ty. kind ) {
276272 ( & ty:: Array ( _, length) , & ty:: Slice ( _) ) => {
@@ -298,48 +294,50 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
298294 self . write_immediate ( val, dest)
299295 }
300296
301- _ => bug ! ( "invalid unsizing {:?} -> {:?}" , src. layout. ty, dest . layout . ty ) ,
297+ _ => bug ! ( "invalid unsizing {:?} -> {:?}" , src. layout. ty, cast_ty ) ,
302298 }
303299 }
304300
305301 fn unsize_into (
306302 & mut self ,
307303 src : OpTy < ' tcx , M :: PointerTag > ,
304+ cast_ty : TyAndLayout < ' tcx > ,
308305 dest : PlaceTy < ' tcx , M :: PointerTag > ,
309306 ) -> InterpResult < ' tcx > {
310- trace ! ( "Unsizing {:?} of type {} into {:?}" , * src, src. layout. ty, dest . layout . ty) ;
311- match ( & src. layout . ty . kind , & dest . layout . ty . kind ) {
312- ( & ty:: Ref ( _, s, _) , & ty:: Ref ( _, d , _) | & ty:: RawPtr ( TypeAndMut { ty : d , .. } ) )
313- | ( & ty:: RawPtr ( TypeAndMut { ty : s, .. } ) , & ty:: RawPtr ( TypeAndMut { ty : d , .. } ) ) => {
314- self . unsize_into_ptr ( src, dest, s, d )
307+ trace ! ( "Unsizing {:?} of type {} into {:?}" , * src, src. layout. ty, cast_ty . ty) ;
308+ match ( & src. layout . ty . kind , & cast_ty . ty . kind ) {
309+ ( & ty:: Ref ( _, s, _) , & ty:: Ref ( _, c , _) | & ty:: RawPtr ( TypeAndMut { ty : c , .. } ) )
310+ | ( & ty:: RawPtr ( TypeAndMut { ty : s, .. } ) , & ty:: RawPtr ( TypeAndMut { ty : c , .. } ) ) => {
311+ self . unsize_into_ptr ( src, dest, s, c )
315312 }
316313 ( & ty:: Adt ( def_a, _) , & ty:: Adt ( def_b, _) ) => {
317314 assert_eq ! ( def_a, def_b) ;
318315 if def_a. is_box ( ) || def_b. is_box ( ) {
319316 if !def_a. is_box ( ) || !def_b. is_box ( ) {
320- bug ! ( "invalid unsizing between {:?} -> {:?}" , src. layout, dest . layout ) ;
317+ bug ! ( "invalid unsizing between {:?} -> {:?}" , src. layout. ty , cast_ty . ty ) ;
321318 }
322319 return self . unsize_into_ptr (
323320 src,
324321 dest,
325322 src. layout . ty . boxed_ty ( ) ,
326- dest . layout . ty . boxed_ty ( ) ,
323+ cast_ty . ty . boxed_ty ( ) ,
327324 ) ;
328325 }
329326
330327 // unsizing of generic struct with pointer fields
331328 // Example: `Arc<T>` -> `Arc<Trait>`
332329 // here we need to increase the size of every &T thin ptr field to a fat ptr
333330 for i in 0 ..src. layout . fields . count ( ) {
334- let dst_field = self . place_field ( dest , i) ?;
335- if dst_field . layout . is_zst ( ) {
331+ let cast_ty_field = cast_ty . field ( self , i) ?;
332+ if cast_ty_field . is_zst ( ) {
336333 continue ;
337334 }
338335 let src_field = self . operand_field ( src, i) ?;
339- if src_field. layout . ty == dst_field. layout . ty {
336+ let dst_field = self . place_field ( dest, i) ?;
337+ if src_field. layout . ty == cast_ty_field. ty {
340338 self . copy_op ( src_field, dst_field) ?;
341339 } else {
342- self . unsize_into ( src_field, dst_field) ?;
340+ self . unsize_into ( src_field, cast_ty_field , dst_field) ?;
343341 }
344342 }
345343 Ok ( ( ) )
0 commit comments