Skip to content

Commit b9b1554

Browse files
committed
Fix unsizing casts
1 parent b97ed1a commit b9b1554

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

src/librustc_mir/interpret/cast.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)