@@ -1112,8 +1112,36 @@ 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 ( matches ! ( instance. def, ty:: InstanceDef :: Virtual ( ..) )
1116
+ && Some ( instance. def_id ( ) ) == tcx. lang_items ( ) . drop_in_place_fn ( ) )
1117
+ || matches ! ( instance. def, ty:: InstanceDef :: DropGlue ( ..) )
1118
+ {
1119
+ // Adjust the type ids of DropGlues
1120
+ //
1121
+ // DropGlues may have indirect calls to one or more given types drop function. Rust allows
1122
+ // for types to be erased to any trait object and retains the drop function for the original
1123
+ // type, which means at the indirect call sites in DropGlues, when typeid_for_fnabi is
1124
+ // called a second time, it only has information after type erasure and it could be a call
1125
+ // on any arbitrary trait object. Normalize them to a synthesized Drop trait object, both on
1126
+ // declaration/definition, and during code generation at call sites so they have the same
1127
+ // type id and match.
1128
+ //
1129
+ // FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of
1130
+ // any other type.
1131
+ //
1132
+ let def_id = tcx
1133
+ . lang_items ( )
1134
+ . drop_trait ( )
1135
+ . unwrap_or_else ( || bug ! ( "typeid_for_instance: couldn't get drop_trait lang item" ) ) ;
1136
+ let predicate = ty:: ExistentialPredicate :: Trait ( ty:: ExistentialTraitRef {
1137
+ def_id : def_id,
1138
+ args : List :: empty ( ) ,
1139
+ } ) ;
1140
+ let predicates = tcx. mk_poly_existential_predicates ( & [ ty:: Binder :: dummy ( predicate) ] ) ;
1141
+ let self_ty = Ty :: new_dynamic ( tcx, predicates, tcx. lifetimes . re_erased , ty:: Dyn ) ;
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 ) ;
1117
1145
}
1118
1146
1119
1147
if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
0 commit comments