@@ -1140,8 +1140,10 @@ pub fn typeid_for_instance<'tcx>(
1140
1140
let predicates = tcx. mk_poly_existential_predicates ( & [ ty:: Binder :: dummy ( predicate) ] ) ;
1141
1141
let self_ty = Ty :: new_dynamic ( tcx, predicates, tcx. lifetimes . re_erased , ty:: Dyn ) ;
1142
1142
instance. args = tcx. mk_args_trait ( self_ty, List :: empty ( ) ) ;
1143
- } else if matches ! ( instance. def, ty:: InstanceDef :: Virtual ( ..) ) {
1144
- instance. args = strip_receiver_auto ( tcx, instance. args ) ;
1143
+ } else if let ty:: InstanceDef :: Virtual ( def_id, _) = instance. def {
1144
+ let upcast_ty = upcast ( tcx, def_id, instance. args ) ;
1145
+ let stripped_ty = strip_receiver_auto ( tcx, upcast_ty) ;
1146
+ instance. args = tcx. mk_args_trait ( stripped_ty, instance. args . into_iter ( ) . skip ( 1 ) ) ;
1145
1147
}
1146
1148
1147
1149
if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
@@ -1190,15 +1192,11 @@ pub fn typeid_for_instance<'tcx>(
1190
1192
typeid_for_fnabi ( tcx, fn_abi, options)
1191
1193
}
1192
1194
1193
- fn strip_receiver_auto < ' tcx > (
1194
- tcx : TyCtxt < ' tcx > ,
1195
- args : ty:: GenericArgsRef < ' tcx > ,
1196
- ) -> ty:: GenericArgsRef < ' tcx > {
1197
- let ty = args. type_at ( 0 ) ;
1195
+ fn strip_receiver_auto < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
1198
1196
let ty:: Dynamic ( preds, lifetime, kind) = ty. kind ( ) else {
1199
1197
bug ! ( "Tried to strip auto traits from non-dynamic type {ty}" ) ;
1200
1198
} ;
1201
- let new_rcvr = if preds. principal ( ) . is_some ( ) {
1199
+ if preds. principal ( ) . is_some ( ) {
1202
1200
let filtered_preds =
1203
1201
tcx. mk_poly_existential_predicates_from_iter ( preds. into_iter ( ) . filter ( |pred| {
1204
1202
!matches ! ( pred. skip_binder( ) , ty:: ExistentialPredicate :: AutoTrait ( ..) )
@@ -1209,8 +1207,7 @@ fn strip_receiver_auto<'tcx>(
1209
1207
// about it. This technically discards the knowledge that it was a type that was made
1210
1208
// into a trait object at some point, but that's not a lot.
1211
1209
tcx. types . unit
1212
- } ;
1213
- tcx. mk_args_trait ( new_rcvr, args. into_iter ( ) . skip ( 1 ) )
1210
+ }
1214
1211
}
1215
1212
1216
1213
#[ instrument( skip( tcx) , ret) ]
@@ -1247,3 +1244,13 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
1247
1244
) ;
1248
1245
Ty :: new_dynamic ( tcx, preds, tcx. lifetimes . re_erased , ty:: Dyn )
1249
1246
}
1247
+
1248
+ fn upcast < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : DefId , args : GenericArgsRef < ' tcx > ) -> Ty < ' tcx > {
1249
+ let self_ty = args. type_at ( 0 ) ;
1250
+ let Some ( trait_id) = tcx. trait_of_item ( def_id) else {
1251
+ // If it's a virtual call to `drop_in_place`, it won't be on a trait.
1252
+ return self_ty;
1253
+ } ;
1254
+ let trait_ref = ty:: TraitRef :: from_method ( tcx, trait_id, args) ;
1255
+ trait_object_ty ( tcx, ty:: Binder :: dummy ( trait_ref) )
1256
+ }
0 commit comments