@@ -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`
106126pub ( 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