@@ -1112,8 +1112,10 @@ pub fn typeid_for_instance<'tcx>(
11121112 mut instance : Instance < ' tcx > ,
11131113 options : TypeIdOptions ,
11141114) -> 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 ) ) ;
11171119 }
11181120
11191121 if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
@@ -1159,15 +1161,11 @@ pub fn typeid_for_instance<'tcx>(
11591161 typeid_for_fnabi ( tcx, fn_abi, options)
11601162}
11611163
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 > {
11671165 let ty:: Dynamic ( preds, lifetime, kind) = ty. kind ( ) else {
11681166 bug ! ( "Tried to strip auto traits from non-dynamic type {ty}" ) ;
11691167 } ;
1170- let new_rcvr = if preds. principal ( ) . is_some ( ) {
1168+ if preds. principal ( ) . is_some ( ) {
11711169 let filtered_preds =
11721170 tcx. mk_poly_existential_predicates_from_iter ( preds. into_iter ( ) . filter ( |pred| {
11731171 !matches ! ( pred. skip_binder( ) , ty:: ExistentialPredicate :: AutoTrait ( ..) )
@@ -1178,8 +1176,7 @@ fn strip_receiver_auto<'tcx>(
11781176 // about it. This technically discards the knowledge that it was a type that was made
11791177 // into a trait object at some point, but that's not a lot.
11801178 tcx. types . unit
1181- } ;
1182- tcx. mk_args_trait ( new_rcvr, args. into_iter ( ) . skip ( 1 ) )
1179+ }
11831180}
11841181
11851182fn 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
12141211 ) ;
12151212 Ty :: new_dynamic ( tcx, preds, tcx. lifetimes . re_erased , ty:: Dyn )
12161213}
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