@@ -1112,8 +1112,10 @@ pub fn typeid_for_instance<'tcx>(
1112
1112
mut instance : Instance < ' tcx > ,
1113
1113
options : TypeIdOptions ,
1114
1114
) -> String {
1115
- if matches ! ( instance. def, ty:: InstanceDef :: Virtual ( ..) ) {
1116
- instance. args = strip_receiver_auto ( tcx, instance. args )
1115
+ if let ty:: InstanceDef :: Virtual ( def_id, _) = instance. def {
1116
+ let upcast_ty = upcast ( tcx, def_id, instance. args ) ;
1117
+ let stripped_ty = strip_receiver_auto ( tcx, upcast_ty) ;
1118
+ instance. args = tcx. mk_args_trait ( stripped_ty, instance. args . into_iter ( ) . skip ( 1 ) ) ;
1117
1119
}
1118
1120
1119
1121
if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
@@ -1159,15 +1161,11 @@ pub fn typeid_for_instance<'tcx>(
1159
1161
typeid_for_fnabi ( tcx, fn_abi, options)
1160
1162
}
1161
1163
1162
- fn strip_receiver_auto < ' tcx > (
1163
- tcx : TyCtxt < ' tcx > ,
1164
- args : ty:: GenericArgsRef < ' tcx > ,
1165
- ) -> ty:: GenericArgsRef < ' tcx > {
1166
- let ty = args. type_at ( 0 ) ;
1164
+ fn strip_receiver_auto < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
1167
1165
let ty:: Dynamic ( preds, lifetime, kind) = ty. kind ( ) else {
1168
1166
bug ! ( "Tried to strip auto traits from non-dynamic type {ty}" ) ;
1169
1167
} ;
1170
- let new_rcvr = if preds. principal ( ) . is_some ( ) {
1168
+ if preds. principal ( ) . is_some ( ) {
1171
1169
let filtered_preds =
1172
1170
tcx. mk_poly_existential_predicates_from_iter ( preds. into_iter ( ) . filter ( |pred| {
1173
1171
!matches ! ( pred. skip_binder( ) , ty:: ExistentialPredicate :: AutoTrait ( ..) )
@@ -1178,8 +1176,7 @@ fn strip_receiver_auto<'tcx>(
1178
1176
// about it. This technically discards the knowledge that it was a type that was made
1179
1177
// into a trait object at some point, but that's not a lot.
1180
1178
tcx. types . unit
1181
- } ;
1182
- tcx. mk_args_trait ( new_rcvr, args. into_iter ( ) . skip ( 1 ) )
1179
+ }
1183
1180
}
1184
1181
1185
1182
fn trait_object_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , poly_trait_ref : ty:: PolyTraitRef < ' tcx > ) -> Ty < ' tcx > {
@@ -1214,3 +1211,13 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
1214
1211
) ;
1215
1212
Ty :: new_dynamic ( tcx, preds, tcx. lifetimes . re_erased , ty:: Dyn )
1216
1213
}
1214
+
1215
+ fn upcast < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : DefId , args : GenericArgsRef < ' tcx > ) -> Ty < ' tcx > {
1216
+ let self_ty = args. type_at ( 0 ) ;
1217
+ let Some ( trait_id) = tcx. trait_of_item ( def_id) else {
1218
+ // If it's a virtual call to `drop_in_place`, it won't be on a trait.
1219
+ return self_ty;
1220
+ } ;
1221
+ let trait_ref = ty:: TraitRef :: from_method ( tcx, trait_id, args) ;
1222
+ trait_object_ty ( tcx, ty:: Binder :: dummy ( trait_ref) )
1223
+ }
0 commit comments