@@ -25,7 +25,12 @@ pub(crate) fn unsized_info<'tcx>(
25
25
. bcx
26
26
. ins ( )
27
27
. 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
+
29
34
let old_info =
30
35
old_info. expect ( "unsized_info: missing old info for trait upcasting coercion" ) ;
31
36
if data_a. principal_def_id ( ) == data_b. principal_def_id ( ) {
@@ -101,6 +106,21 @@ fn unsize_ptr<'tcx>(
101
106
}
102
107
}
103
108
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
+
104
124
/// Coerce `src`, which is a reference to a value of type `src_ty`,
105
125
/// to a value of type `dst_ty` and store the result in `dst`
106
126
pub ( crate ) fn coerce_unsized_into < ' tcx > (
@@ -152,14 +172,16 @@ pub(crate) fn coerce_dyn_star<'tcx>(
152
172
src : CValue < ' tcx > ,
153
173
dst : CPlace < ' tcx > ,
154
174
) {
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) )
159
178
} else {
160
- bug ! ( "Only valid to do a DynStar cast into a DynStar type" )
179
+ let data = src. load_scalar ( fx) ;
180
+ ( data, None )
161
181
} ;
162
182
183
+ let ( data, vtable) = cast_to_dyn_star ( fx, data, src. layout ( ) , dst. layout ( ) . ty , extra) ;
184
+
163
185
dst. write_cvalue ( fx, CValue :: by_val_pair ( data, vtable, dst. layout ( ) ) ) ;
164
186
}
165
187
0 commit comments