@@ -625,6 +625,31 @@ fn dump_vtable_entries<'tcx>(
625625 tcx. sess . struct_span_err ( sp, & msg) . emit ( ) ;
626626}
627627
628+ fn own_existential_vtable_entries < ' tcx > (
629+ tcx : TyCtxt < ' tcx > ,
630+ trait_ref : ty:: PolyExistentialTraitRef < ' tcx > ,
631+ ) -> & ' tcx [ DefId ] {
632+ let trait_methods = tcx
633+ . associated_items ( trait_ref. def_id ( ) )
634+ . in_definition_order ( )
635+ . filter ( |item| item. kind == ty:: AssocKind :: Fn ) ;
636+ // Now list each method's DefId (for within its trait).
637+ let own_entries = trait_methods. filter_map ( move |trait_method| {
638+ debug ! ( "own_existential_vtable_entry: trait_method={:?}" , trait_method) ;
639+ let def_id = trait_method. def_id ;
640+
641+ // Some methods cannot be called on an object; skip those.
642+ if !is_vtable_safe_method ( tcx, trait_ref. def_id ( ) , & trait_method) {
643+ debug ! ( "own_existential_vtable_entry: not vtable safe" ) ;
644+ return None ;
645+ }
646+
647+ Some ( def_id)
648+ } ) ;
649+
650+ tcx. arena . alloc_from_iter ( own_entries. into_iter ( ) )
651+ }
652+
628653/// Given a trait `trait_ref`, iterates the vtable entries
629654/// that come from `trait_ref`, including its supertraits.
630655fn vtable_entries < ' tcx > (
@@ -641,21 +666,15 @@ fn vtable_entries<'tcx>(
641666 entries. extend ( COMMON_VTABLE_ENTRIES ) ;
642667 }
643668 VtblSegment :: TraitOwnEntries { trait_ref, emit_vptr } => {
644- let trait_methods = tcx
645- . associated_items ( trait_ref. def_id ( ) )
646- . in_definition_order ( )
647- . filter ( |item| item. kind == ty:: AssocKind :: Fn ) ;
648- // Now list each method's DefId and InternalSubsts (for within its trait).
649- // If the method can never be called from this object, produce `Vacant`.
650- let own_entries = trait_methods. filter_map ( move |trait_method| {
651- debug ! ( "vtable_entries: trait_method={:?}" , trait_method) ;
652- let def_id = trait_method. def_id ;
653-
654- // Some methods cannot be called on an object; skip those.
655- if !is_vtable_safe_method ( tcx, trait_ref. def_id ( ) , & trait_method) {
656- debug ! ( "vtable_entries: not vtable safe" ) ;
657- return None ;
658- }
669+ let existential_trait_ref = trait_ref
670+ . map_bound ( |trait_ref| ty:: ExistentialTraitRef :: erase_self_ty ( tcx, trait_ref) ) ;
671+
672+ // Lookup the shape of vtable for the trait.
673+ let own_existential_entries =
674+ tcx. own_existential_vtable_entries ( existential_trait_ref) ;
675+
676+ let own_entries = own_existential_entries. iter ( ) . copied ( ) . map ( |def_id| {
677+ debug ! ( "vtable_entries: trait_method={:?}" , def_id) ;
659678
660679 // The method may have some early-bound lifetimes; add regions for those.
661680 let substs = trait_ref. map_bound ( |trait_ref| {
@@ -681,7 +700,7 @@ fn vtable_entries<'tcx>(
681700 let predicates = tcx. predicates_of ( def_id) . instantiate_own ( tcx, substs) ;
682701 if impossible_predicates ( tcx, predicates. predicates ) {
683702 debug ! ( "vtable_entries: predicates do not hold" ) ;
684- return Some ( VtblEntry :: Vacant ) ;
703+ return VtblEntry :: Vacant ;
685704 }
686705
687706 let instance = ty:: Instance :: resolve_for_vtable (
@@ -691,7 +710,7 @@ fn vtable_entries<'tcx>(
691710 substs,
692711 )
693712 . expect ( "resolution failed during building vtable representation" ) ;
694- Some ( VtblEntry :: Method ( instance) )
713+ VtblEntry :: Method ( instance)
695714 } ) ;
696715
697716 entries. extend ( own_entries) ;
@@ -804,6 +823,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
804823 specialization_graph_of : specialize:: specialization_graph_provider,
805824 specializes : specialize:: specializes,
806825 codegen_fulfill_obligation : codegen:: codegen_fulfill_obligation,
826+ own_existential_vtable_entries,
807827 vtable_entries,
808828 vtable_trait_upcasting_coercion_new_vptr_slot,
809829 subst_and_check_impossible_predicates,
0 commit comments