@@ -625,6 +625,31 @@ fn dump_vtable_entries<'tcx>(
625
625
tcx. sess . struct_span_err ( sp, & msg) . emit ( ) ;
626
626
}
627
627
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
+
628
653
/// Given a trait `trait_ref`, iterates the vtable entries
629
654
/// that come from `trait_ref`, including its supertraits.
630
655
fn vtable_entries < ' tcx > (
@@ -641,21 +666,15 @@ fn vtable_entries<'tcx>(
641
666
entries. extend ( COMMON_VTABLE_ENTRIES ) ;
642
667
}
643
668
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) ;
659
678
660
679
// The method may have some early-bound lifetimes; add regions for those.
661
680
let substs = trait_ref. map_bound ( |trait_ref| {
@@ -681,7 +700,7 @@ fn vtable_entries<'tcx>(
681
700
let predicates = tcx. predicates_of ( def_id) . instantiate_own ( tcx, substs) ;
682
701
if impossible_predicates ( tcx, predicates. predicates ) {
683
702
debug ! ( "vtable_entries: predicates do not hold" ) ;
684
- return Some ( VtblEntry :: Vacant ) ;
703
+ return VtblEntry :: Vacant ;
685
704
}
686
705
687
706
let instance = ty:: Instance :: resolve_for_vtable (
@@ -691,7 +710,7 @@ fn vtable_entries<'tcx>(
691
710
substs,
692
711
)
693
712
. expect ( "resolution failed during building vtable representation" ) ;
694
- Some ( VtblEntry :: Method ( instance) )
713
+ VtblEntry :: Method ( instance)
695
714
} ) ;
696
715
697
716
entries. extend ( own_entries) ;
@@ -804,6 +823,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
804
823
specialization_graph_of : specialize:: specialization_graph_provider,
805
824
specializes : specialize:: specializes,
806
825
codegen_fulfill_obligation : codegen:: codegen_fulfill_obligation,
826
+ own_existential_vtable_entries,
807
827
vtable_entries,
808
828
vtable_trait_upcasting_coercion_new_vptr_slot,
809
829
subst_and_check_impossible_predicates,
0 commit comments