Skip to content

Commit 2470ad3

Browse files
committed
Allow dyn* upcasting
1 parent 7a9abf5 commit 2470ad3

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

src/unsize.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ pub(crate) fn unsized_info<'tcx>(
2525
.bcx
2626
.ins()
2727
.iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
28-
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
28+
(
29+
&ty::Dynamic(ref data_a, _, src_dyn_kind),
30+
&ty::Dynamic(ref data_b, _, target_dyn_kind),
31+
) => {
32+
assert_eq!(src_dyn_kind, target_dyn_kind);
33+
2934
let old_info =
3035
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
3136
if data_a.principal_def_id() == data_b.principal_def_id() {
@@ -101,6 +106,21 @@ fn unsize_ptr<'tcx>(
101106
}
102107
}
103108

109+
/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type.
110+
pub(crate) fn cast_to_dyn_star<'tcx>(
111+
fx: &mut FunctionCx<'_, '_, 'tcx>,
112+
src: Value,
113+
src_ty_and_layout: TyAndLayout<'tcx>,
114+
dst_ty: Ty<'tcx>,
115+
old_info: Option<Value>,
116+
) -> (Value, Value) {
117+
assert!(
118+
matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
119+
"destination type must be a dyn*"
120+
);
121+
(src, unsized_info(fx, src_ty_and_layout.ty, dst_ty, old_info))
122+
}
123+
104124
/// Coerce `src`, which is a reference to a value of type `src_ty`,
105125
/// to a value of type `dst_ty` and store the result in `dst`
106126
pub(crate) fn coerce_unsized_into<'tcx>(
@@ -152,14 +172,16 @@ pub(crate) fn coerce_dyn_star<'tcx>(
152172
src: CValue<'tcx>,
153173
dst: CPlace<'tcx>,
154174
) {
155-
let data = src.load_scalar(fx);
156-
157-
let vtable = if let ty::Dynamic(data, _, ty::DynStar) = dst.layout().ty.kind() {
158-
crate::vtable::get_vtable(fx, src.layout().ty, data.principal())
175+
let (data, extra) = if let ty::Dynamic(_, _, ty::DynStar) = src.layout().ty.kind() {
176+
let (data, vtable) = src.load_scalar_pair(fx);
177+
(data, Some(vtable))
159178
} else {
160-
bug!("Only valid to do a DynStar cast into a DynStar type")
179+
let data = src.load_scalar(fx);
180+
(data, None)
161181
};
162182

183+
let (data, vtable) = cast_to_dyn_star(fx, data, src.layout(), dst.layout().ty, extra);
184+
163185
dst.write_cvalue(fx, CValue::by_val_pair(data, vtable, dst.layout()));
164186
}
165187

0 commit comments

Comments
 (0)