@@ -650,53 +650,55 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
650
650
/// Given a trait `trait_ref`, iterates the vtable entries
651
651
/// that come from `trait_ref`, including its supertraits.
652
652
#[ 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 > (
654
654
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
655
655
trait_ref : ty:: PolyTraitRef < ' tcx > )
656
- -> impl Iterator < Item = Option < ( DefId , & ' tcx Substs < ' tcx > ) > > + ' a
656
+ -> Rc < Vec < Option < ( DefId , & ' tcx Substs < ' tcx > ) > > >
657
657
{
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
+ )
700
702
}
701
703
702
704
impl < ' tcx , O > Obligation < ' tcx , O > {
@@ -836,6 +838,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
836
838
specialization_graph_of : specialize:: specialization_graph_provider,
837
839
specializes : specialize:: specializes,
838
840
trans_fulfill_obligation : trans:: trans_fulfill_obligation,
841
+ vtable_methods,
839
842
..* providers
840
843
} ;
841
844
}
@@ -846,6 +849,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
846
849
specialization_graph_of : specialize:: specialization_graph_provider,
847
850
specializes : specialize:: specializes,
848
851
trans_fulfill_obligation : trans:: trans_fulfill_obligation,
852
+ vtable_methods,
849
853
..* providers
850
854
} ;
851
855
}
0 commit comments