@@ -25,12 +25,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
25
25
// FIXME: In which cases should we trigger UB when the source is uninit?
26
26
match cast_kind {
27
27
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) ?;
34
30
}
35
31
36
32
Misc => {
@@ -266,11 +262,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
266
262
dest : PlaceTy < ' tcx , M :: PointerTag > ,
267
263
// The pointee types
268
264
source_ty : Ty < ' tcx > ,
269
- dest_ty : Ty < ' tcx > ,
265
+ cast_ty : Ty < ' tcx > ,
270
266
) -> InterpResult < ' tcx > {
271
267
// A<Struct> -> A<Trait> conversion
272
268
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 ) ;
274
270
275
271
match ( & src_pointee_ty. kind , & dest_pointee_ty. kind ) {
276
272
( & ty:: Array ( _, length) , & ty:: Slice ( _) ) => {
@@ -298,48 +294,50 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
298
294
self . write_immediate ( val, dest)
299
295
}
300
296
301
- _ => bug ! ( "invalid unsizing {:?} -> {:?}" , src. layout. ty, dest . layout . ty ) ,
297
+ _ => bug ! ( "invalid unsizing {:?} -> {:?}" , src. layout. ty, cast_ty ) ,
302
298
}
303
299
}
304
300
305
301
fn unsize_into (
306
302
& mut self ,
307
303
src : OpTy < ' tcx , M :: PointerTag > ,
304
+ cast_ty : TyAndLayout < ' tcx > ,
308
305
dest : PlaceTy < ' tcx , M :: PointerTag > ,
309
306
) -> 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 )
315
312
}
316
313
( & ty:: Adt ( def_a, _) , & ty:: Adt ( def_b, _) ) => {
317
314
assert_eq ! ( def_a, def_b) ;
318
315
if def_a. is_box ( ) || def_b. is_box ( ) {
319
316
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 ) ;
321
318
}
322
319
return self . unsize_into_ptr (
323
320
src,
324
321
dest,
325
322
src. layout . ty . boxed_ty ( ) ,
326
- dest . layout . ty . boxed_ty ( ) ,
323
+ cast_ty . ty . boxed_ty ( ) ,
327
324
) ;
328
325
}
329
326
330
327
// unsizing of generic struct with pointer fields
331
328
// Example: `Arc<T>` -> `Arc<Trait>`
332
329
// here we need to increase the size of every &T thin ptr field to a fat ptr
333
330
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 ( ) {
336
333
continue ;
337
334
}
338
335
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 {
340
338
self . copy_op ( src_field, dst_field) ?;
341
339
} else {
342
- self . unsize_into ( src_field, dst_field) ?;
340
+ self . unsize_into ( src_field, cast_ty_field , dst_field) ?;
343
341
}
344
342
}
345
343
Ok ( ( ) )
0 commit comments