@@ -1115,51 +1115,31 @@ pub fn typeid_for_instance<'tcx>(
1115
1115
instance. args = strip_receiver_auto ( tcx, instance. args )
1116
1116
}
1117
1117
1118
+ if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
1119
+ && let Some ( trait_ref) = tcx. impl_trait_ref ( impl_id)
1120
+ {
1121
+ // Trait methods will have a Self polymorphic parameter, where the concreteized
1122
+ // implementatation will not. We need to walk back to the more general trait method
1123
+ let trait_ref = trait_ref. instantiate ( tcx, instance. args ) ;
1124
+ let invoke_ty = tcx. trait_object_ty ( ty:: Binder :: dummy ( trait_ref) ) ;
1125
+ let method_id = tcx
1126
+ . impl_item_implementor_ids ( impl_id)
1127
+ . items ( )
1128
+ . filter_map ( |( trait_method, impl_method) | {
1129
+ ( * impl_method == instance. def_id ( ) ) . then_some ( * trait_method)
1130
+ } )
1131
+ . min ( )
1132
+ . unwrap ( ) ;
1133
+ instance. def = ty:: InstanceDef :: Virtual ( method_id, 0 ) ;
1134
+ instance. args = tcx. mk_args_trait ( invoke_ty, trait_ref. args . into_iter ( ) . skip ( 1 ) ) ;
1135
+ }
1136
+
1118
1137
let fn_abi = tcx
1119
1138
. fn_abi_of_instance ( tcx. param_env ( instance. def_id ( ) ) . and ( ( instance, ty:: List :: empty ( ) ) ) )
1120
1139
. unwrap_or_else ( |instance| {
1121
1140
bug ! ( "typeid_for_instance: couldn't get fn_abi of instance {:?}" , instance)
1122
1141
} ) ;
1123
1142
1124
- // If this instance is a method and self is a reference, get the impl it belongs to
1125
- let impl_def_id = tcx. impl_of_method ( instance. def_id ( ) ) ;
1126
- if impl_def_id. is_some ( ) && !fn_abi. args . is_empty ( ) && fn_abi. args [ 0 ] . layout . ty . is_ref ( ) {
1127
- // If this impl is not an inherent impl, get the trait it implements
1128
- if let Some ( trait_ref) = tcx. impl_trait_ref ( impl_def_id. unwrap ( ) ) {
1129
- // Transform the concrete self into a reference to a trait object
1130
- let existential_predicate = trait_ref. map_bound ( |trait_ref| {
1131
- ty:: ExistentialPredicate :: Trait ( ty:: ExistentialTraitRef :: erase_self_ty (
1132
- tcx, trait_ref,
1133
- ) )
1134
- } ) ;
1135
- let existential_predicates = tcx. mk_poly_existential_predicates ( & [ ty:: Binder :: dummy (
1136
- existential_predicate. skip_binder ( ) ,
1137
- ) ] ) ;
1138
- // Is the concrete self mutable?
1139
- let self_ty = if fn_abi. args [ 0 ] . layout . ty . is_mutable_ptr ( ) {
1140
- Ty :: new_mut_ref (
1141
- tcx,
1142
- tcx. lifetimes . re_erased ,
1143
- Ty :: new_dynamic ( tcx, existential_predicates, tcx. lifetimes . re_erased , ty:: Dyn ) ,
1144
- )
1145
- } else {
1146
- Ty :: new_imm_ref (
1147
- tcx,
1148
- tcx. lifetimes . re_erased ,
1149
- Ty :: new_dynamic ( tcx, existential_predicates, tcx. lifetimes . re_erased , ty:: Dyn ) ,
1150
- )
1151
- } ;
1152
-
1153
- // Replace the concrete self in an fn_abi clone by the reference to a trait object
1154
- let mut fn_abi = fn_abi. clone ( ) ;
1155
- // HACK(rcvalle): It is okay to not replace or update the entire ArgAbi here because the
1156
- // other fields are never used.
1157
- fn_abi. args [ 0 ] . layout . ty = self_ty;
1158
-
1159
- return typeid_for_fnabi ( tcx, & fn_abi, options) ;
1160
- }
1161
- }
1162
-
1163
1143
typeid_for_fnabi ( tcx, fn_abi, options)
1164
1144
}
1165
1145
0 commit comments