@@ -650,53 +650,55 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
650650/// Given a trait `trait_ref`, iterates the vtable entries
651651/// that come from `trait_ref`, including its supertraits.
652652#[ inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
653- pub fn get_vtable_methods < ' a , ' tcx > (
653+ fn vtable_methods < ' a , ' tcx > (
654654 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
655655 trait_ref : ty:: PolyTraitRef < ' tcx > )
656- -> impl Iterator < Item = Option < ( DefId , & ' tcx Substs < ' tcx > ) > > + ' a
656+ -> Rc < Vec < Option < ( DefId , & ' tcx Substs < ' tcx > ) > > >
657657{
658- debug ! ( "get_vtable_methods({:?})" , trait_ref) ;
659-
660- supertraits ( tcx, trait_ref) . flat_map ( move |trait_ref| {
661- let trait_methods = tcx. associated_items ( trait_ref. def_id ( ) )
662- . filter ( |item| item. kind == ty:: AssociatedKind :: Method ) ;
663-
664- // Now list each method's DefId and Substs (for within its trait).
665- // If the method can never be called from this object, produce None.
666- trait_methods. map ( move |trait_method| {
667- debug ! ( "get_vtable_methods: trait_method={:?}" , trait_method) ;
668- let def_id = trait_method. def_id ;
669-
670- // Some methods cannot be called on an object; skip those.
671- if !tcx. is_vtable_safe_method ( trait_ref. def_id ( ) , & trait_method) {
672- debug ! ( "get_vtable_methods: not vtable safe" ) ;
673- return None ;
674- }
675-
676- // the method may have some early-bound lifetimes, add
677- // regions for those
678- let substs = Substs :: for_item ( tcx, def_id,
679- |_, _| tcx. types . re_erased ,
680- |def, _| trait_ref. substs ( ) . type_for_def ( def) ) ;
681-
682- // the trait type may have higher-ranked lifetimes in it;
683- // so erase them if they appear, so that we get the type
684- // at some particular call site
685- let substs = tcx. erase_late_bound_regions_and_normalize ( & ty:: Binder ( substs) ) ;
686-
687- // It's possible that the method relies on where clauses that
688- // do not hold for this particular set of type parameters.
689- // Note that this method could then never be called, so we
690- // do not want to try and trans it, in that case (see #23435).
691- let predicates = tcx. predicates_of ( def_id) . instantiate_own ( tcx, substs) ;
692- if !normalize_and_test_predicates ( tcx, predicates. predicates ) {
693- debug ! ( "get_vtable_methods: predicates do not hold" ) ;
694- return None ;
695- }
696-
697- Some ( ( def_id, substs) )
698- } )
699- } )
658+ debug ! ( "vtable_methods({:?})" , trait_ref) ;
659+
660+ Rc :: new (
661+ supertraits ( tcx, trait_ref) . flat_map ( move |trait_ref| {
662+ let trait_methods = tcx. associated_items ( trait_ref. def_id ( ) )
663+ . filter ( |item| item. kind == ty:: AssociatedKind :: Method ) ;
664+
665+ // Now list each method's DefId and Substs (for within its trait).
666+ // If the method can never be called from this object, produce None.
667+ trait_methods. map ( move |trait_method| {
668+ debug ! ( "vtable_methods: trait_method={:?}" , trait_method) ;
669+ let def_id = trait_method. def_id ;
670+
671+ // Some methods cannot be called on an object; skip those.
672+ if !tcx. is_vtable_safe_method ( trait_ref. def_id ( ) , & trait_method) {
673+ debug ! ( "vtable_methods: not vtable safe" ) ;
674+ return None ;
675+ }
676+
677+ // the method may have some early-bound lifetimes, add
678+ // regions for those
679+ let substs = Substs :: for_item ( tcx, def_id,
680+ |_, _| tcx. types . re_erased ,
681+ |def, _| trait_ref. substs ( ) . type_for_def ( def) ) ;
682+
683+ // the trait type may have higher-ranked lifetimes in it;
684+ // so erase them if they appear, so that we get the type
685+ // at some particular call site
686+ let substs = tcx. erase_late_bound_regions_and_normalize ( & ty:: Binder ( substs) ) ;
687+
688+ // It's possible that the method relies on where clauses that
689+ // do not hold for this particular set of type parameters.
690+ // Note that this method could then never be called, so we
691+ // do not want to try and trans it, in that case (see #23435).
692+ let predicates = tcx. predicates_of ( def_id) . instantiate_own ( tcx, substs) ;
693+ if !normalize_and_test_predicates ( tcx, predicates. predicates ) {
694+ debug ! ( "vtable_methods: predicates do not hold" ) ;
695+ return None ;
696+ }
697+
698+ Some ( ( def_id, substs) )
699+ } )
700+ } ) . collect ( )
701+ )
700702}
701703
702704impl < ' tcx , O > Obligation < ' tcx , O > {
@@ -836,6 +838,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
836838 specialization_graph_of : specialize:: specialization_graph_provider,
837839 specializes : specialize:: specializes,
838840 trans_fulfill_obligation : trans:: trans_fulfill_obligation,
841+ vtable_methods,
839842 ..* providers
840843 } ;
841844}
@@ -846,6 +849,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
846849 specialization_graph_of : specialize:: specialization_graph_provider,
847850 specializes : specialize:: specializes,
848851 trans_fulfill_obligation : trans:: trans_fulfill_obligation,
852+ vtable_methods,
849853 ..* providers
850854 } ;
851855}
0 commit comments