@@ -147,16 +147,21 @@ fn prepare_vtable_segments_inner<'tcx, T>(
147147 }
148148 }
149149
150- // Other than the left-most path, vptr should be emitted for each trait.
151- emit_vptr_on_new_entry = true ;
152-
153150 // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
154151 while let Some ( ( inner_most_trait_ref, emit_vptr, mut siblings) ) = stack. pop ( ) {
155152 segment_visitor ( VtblSegment :: TraitOwnEntries {
156153 trait_ref : inner_most_trait_ref,
157154 emit_vptr,
158155 } ) ?;
159156
157+ // If we've emitted (fed to `segment_visitor`) a trait that has methods present in the vtable,
158+ // we'll need to emit vptrs from now on.
159+ if !emit_vptr_on_new_entry
160+ && has_own_existential_vtable_entries ( tcx, inner_most_trait_ref. def_id ( ) )
161+ {
162+ emit_vptr_on_new_entry = true ;
163+ }
164+
160165 if let Some ( next_inner_most_trait_ref) =
161166 siblings. find ( |& sibling| visited. insert ( sibling. to_predicate ( tcx) ) )
162167 {
@@ -196,11 +201,23 @@ fn dump_vtable_entries<'tcx>(
196201 } ) ;
197202}
198203
204+ fn has_own_existential_vtable_entries ( tcx : TyCtxt < ' _ > , trait_def_id : DefId ) -> bool {
205+ own_existential_vtable_entries_iter ( tcx, trait_def_id) . next ( ) . is_some ( )
206+ }
207+
199208fn own_existential_vtable_entries ( tcx : TyCtxt < ' _ > , trait_def_id : DefId ) -> & [ DefId ] {
209+ tcx. arena . alloc_from_iter ( own_existential_vtable_entries_iter ( tcx, trait_def_id) )
210+ }
211+
212+ fn own_existential_vtable_entries_iter (
213+ tcx : TyCtxt < ' _ > ,
214+ trait_def_id : DefId ,
215+ ) -> impl Iterator < Item = DefId > + ' _ {
200216 let trait_methods = tcx
201217 . associated_items ( trait_def_id)
202218 . in_definition_order ( )
203219 . filter ( |item| item. kind == ty:: AssocKind :: Fn ) ;
220+
204221 // Now list each method's DefId (for within its trait).
205222 let own_entries = trait_methods. filter_map ( move |& trait_method| {
206223 debug ! ( "own_existential_vtable_entry: trait_method={:?}" , trait_method) ;
@@ -215,7 +232,7 @@ fn own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &[Def
215232 Some ( def_id)
216233 } ) ;
217234
218- tcx . arena . alloc_from_iter ( own_entries. into_iter ( ) )
235+ own_entries
219236}
220237
221238/// Given a trait `trait_ref`, iterates the vtable entries
0 commit comments