@@ -1114,8 +1114,10 @@ pub fn typeid_for_instance<'tcx>(
1114
1114
mut instance : Instance < ' tcx > ,
1115
1115
options : TypeIdOptions ,
1116
1116
) -> String {
1117
- if matches ! ( instance. def, ty:: InstanceDef :: Virtual ( ..) ) {
1118
- instance. args = strip_receiver_auto ( tcx, instance. args )
1117
+ if let ty:: InstanceDef :: Virtual ( def_id, _) = instance. def {
1118
+ let upcast_ty = upcast ( tcx, def_id, instance. args ) ;
1119
+ let stripped_ty = strip_receiver_auto ( tcx, upcast_ty) ;
1120
+ instance. args = tcx. mk_args_trait ( stripped_ty, instance. args . into_iter ( ) . skip ( 1 ) ) ;
1119
1121
}
1120
1122
1121
1123
if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
@@ -1146,11 +1148,7 @@ pub fn typeid_for_instance<'tcx>(
1146
1148
typeid_for_fnabi ( tcx, fn_abi, options)
1147
1149
}
1148
1150
1149
- fn strip_receiver_auto < ' tcx > (
1150
- tcx : TyCtxt < ' tcx > ,
1151
- args : ty:: GenericArgsRef < ' tcx > ,
1152
- ) -> ty:: GenericArgsRef < ' tcx > {
1153
- let ty = args. type_at ( 0 ) ;
1151
+ fn strip_receiver_auto < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
1154
1152
let ty:: Dynamic ( preds, lifetime, kind) = ty. kind ( ) else {
1155
1153
bug ! ( "Tried to strip auto traits from non-dynamic type {ty}" ) ;
1156
1154
} ;
@@ -1162,8 +1160,7 @@ fn strip_receiver_auto<'tcx>(
1162
1160
} else {
1163
1161
ty:: List :: empty ( )
1164
1162
} ;
1165
- let new_rcvr = Ty :: new_dynamic ( tcx, filtered_preds, * lifetime, * kind) ;
1166
- tcx. mk_args_trait ( new_rcvr, args. into_iter ( ) . skip ( 1 ) )
1163
+ Ty :: new_dynamic ( tcx, filtered_preds, * lifetime, * kind)
1167
1164
}
1168
1165
1169
1166
fn trait_object_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , poly_trait_ref : ty:: PolyTraitRef < ' tcx > ) -> Ty < ' tcx > {
@@ -1195,3 +1192,13 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
1195
1192
tcx. mk_poly_existential_predicates_from_iter ( iter:: once ( principal_pred) . chain ( assoc_preds) ) ;
1196
1193
Ty :: new_dynamic ( tcx, preds, tcx. lifetimes . re_erased , ty:: Dyn )
1197
1194
}
1195
+
1196
+ fn upcast < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : DefId , args : GenericArgsRef < ' tcx > ) -> Ty < ' tcx > {
1197
+ let self_ty = args. type_at ( 0 ) ;
1198
+ let Some ( trait_id) = tcx. trait_of_item ( def_id) else {
1199
+ // If it's a virtual call to `drop_in_place`, it won't be on a trait.
1200
+ return self_ty;
1201
+ } ;
1202
+ let trait_ref = ty:: TraitRef :: from_method ( tcx, trait_id, args) ;
1203
+ trait_object_ty ( tcx, ty:: Binder :: dummy ( trait_ref) )
1204
+ }
0 commit comments