@@ -1140,8 +1140,10 @@ pub fn typeid_for_instance<'tcx>(
11401140 let predicates = tcx. mk_poly_existential_predicates ( & [ ty:: Binder :: dummy ( predicate) ] ) ;
11411141 let self_ty = Ty :: new_dynamic ( tcx, predicates, tcx. lifetimes . re_erased , ty:: Dyn ) ;
11421142 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 ) ) ;
11451147 }
11461148
11471149 if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
@@ -1190,15 +1192,11 @@ pub fn typeid_for_instance<'tcx>(
11901192 typeid_for_fnabi ( tcx, fn_abi, options)
11911193}
11921194
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 > {
11981196 let ty:: Dynamic ( preds, lifetime, kind) = ty. kind ( ) else {
11991197 bug ! ( "Tried to strip auto traits from non-dynamic type {ty}" ) ;
12001198 } ;
1201- let new_rcvr = if preds. principal ( ) . is_some ( ) {
1199+ if preds. principal ( ) . is_some ( ) {
12021200 let filtered_preds =
12031201 tcx. mk_poly_existential_predicates_from_iter ( preds. into_iter ( ) . filter ( |pred| {
12041202 !matches ! ( pred. skip_binder( ) , ty:: ExistentialPredicate :: AutoTrait ( ..) )
@@ -1209,8 +1207,7 @@ fn strip_receiver_auto<'tcx>(
12091207 // about it. This technically discards the knowledge that it was a type that was made
12101208 // into a trait object at some point, but that's not a lot.
12111209 tcx. types . unit
1212- } ;
1213- tcx. mk_args_trait ( new_rcvr, args. into_iter ( ) . skip ( 1 ) )
1210+ }
12141211}
12151212
12161213#[ instrument( skip( tcx) , ret) ]
@@ -1247,3 +1244,13 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
12471244 ) ;
12481245 Ty :: new_dynamic ( tcx, preds, tcx. lifetimes . re_erased , ty:: Dyn )
12491246}
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