@@ -745,6 +745,19 @@ fn encode_ty<'tcx>(
745
745
typeid
746
746
}
747
747
748
+ /// Creates a trait object.
749
+ #[ inline]
750
+ fn new_dynamic_trait < ' tcx > (
751
+ tcx : TyCtxt < ' tcx > ,
752
+ def_id : DefId ,
753
+ args : GenericArgsRef < ' tcx > ,
754
+ ) -> Ty < ' tcx > {
755
+ let predicate =
756
+ ty:: ExistentialPredicate :: Trait ( ty:: ExistentialTraitRef { def_id : def_id, args : args } ) ;
757
+ let predicates = tcx. mk_poly_existential_predicates ( & [ ty:: Binder :: dummy ( predicate) ] ) ;
758
+ Ty :: new_dynamic ( tcx, predicates, tcx. lifetimes . re_erased , ty:: Dyn )
759
+ }
760
+
748
761
/// Transforms predicates for being encoded and used in the substitution dictionary.
749
762
fn transform_predicates < ' tcx > (
750
763
tcx : TyCtxt < ' tcx > ,
@@ -1112,8 +1125,31 @@ pub fn typeid_for_instance<'tcx>(
1112
1125
mut instance : Instance < ' tcx > ,
1113
1126
options : TypeIdOptions ,
1114
1127
) -> String {
1115
- if matches ! ( instance. def, ty:: InstanceDef :: Virtual ( ..) ) {
1116
- instance. args = strip_receiver_auto ( tcx, instance. args )
1128
+ if ( matches ! ( instance. def, ty:: InstanceDef :: Virtual ( ..) )
1129
+ && instance. def_id ( ) == tcx. lang_items ( ) . drop_in_place_fn ( ) . unwrap ( ) )
1130
+ || matches ! ( instance. def, ty:: InstanceDef :: DropGlue ( ..) )
1131
+ {
1132
+ // Adjust the type ids of DropGlues
1133
+ //
1134
+ // DropGlues may have indirect calls to one or more given types drop function. Rust allows
1135
+ // for types to be erased to any trait object and retains the drop function for the original
1136
+ // type, which means at the indirect call sites in DropGlues, when typeid_for_fnabi is
1137
+ // called a second time, it only has information after type erasure and it could be a call
1138
+ // on any arbitrary trait object. Normalize them to a synthesized Drop trait object, both on
1139
+ // declaration/definition, and during code generation at call sites so they have the same
1140
+ // type id and match.
1141
+ //
1142
+ // FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of
1143
+ // any other type.
1144
+ //
1145
+ let self_ty = Ty :: new_mut_ref (
1146
+ tcx,
1147
+ tcx. lifetimes . re_erased ,
1148
+ new_dynamic_trait ( tcx, tcx. lang_items ( ) . drop_trait ( ) . unwrap ( ) , List :: empty ( ) ) ,
1149
+ ) ;
1150
+ instance. args = tcx. mk_args_trait ( self_ty, List :: empty ( ) ) ;
1151
+ } else if matches ! ( instance. def, ty:: InstanceDef :: Virtual ( ..) ) {
1152
+ instance. args = strip_receiver_auto ( tcx, instance. args ) ;
1117
1153
}
1118
1154
1119
1155
if let Some ( impl_id) = tcx. impl_of_method ( instance. def_id ( ) )
0 commit comments