@@ -2,9 +2,12 @@ use smallvec::smallvec;
22
33use rustc_data_structures:: fx:: FxHashSet ;
44use rustc_middle:: ty:: outlives:: Component ;
5- use rustc_middle:: ty:: { self , ToPolyTraitRef , TyCtxt } ;
5+ use rustc_middle:: ty:: { self , ToPolyTraitRef , ToPredicate , TyCtxt , WithConstness } ;
66
7- fn anonymize_predicate < ' tcx > ( tcx : TyCtxt < ' tcx > , pred : & ty:: Predicate < ' tcx > ) -> ty:: Predicate < ' tcx > {
7+ pub fn anonymize_predicate < ' tcx > (
8+ tcx : TyCtxt < ' tcx > ,
9+ pred : & ty:: Predicate < ' tcx > ,
10+ ) -> ty:: Predicate < ' tcx > {
811 match * pred {
912 ty:: Predicate :: Trait ( ref data, constness) => {
1013 ty:: Predicate :: Trait ( tcx. anonymize_late_bound_regions ( data) , constness)
@@ -88,6 +91,21 @@ pub struct Elaborator<'tcx> {
8891 visited : PredicateSet < ' tcx > ,
8992}
9093
94+ pub fn elaborate_trait_ref < ' tcx > (
95+ tcx : TyCtxt < ' tcx > ,
96+ trait_ref : ty:: PolyTraitRef < ' tcx > ,
97+ ) -> Elaborator < ' tcx > {
98+ elaborate_predicates ( tcx, vec ! [ trait_ref. without_const( ) . to_predicate( ) ] )
99+ }
100+
101+ pub fn elaborate_trait_refs < ' tcx > (
102+ tcx : TyCtxt < ' tcx > ,
103+ trait_refs : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
104+ ) -> Elaborator < ' tcx > {
105+ let predicates = trait_refs. map ( |trait_ref| trait_ref. without_const ( ) . to_predicate ( ) ) . collect ( ) ;
106+ elaborate_predicates ( tcx, predicates)
107+ }
108+
91109pub fn elaborate_predicates < ' tcx > (
92110 tcx : TyCtxt < ' tcx > ,
93111 mut predicates : Vec < ty:: Predicate < ' tcx > > ,
@@ -98,6 +116,10 @@ pub fn elaborate_predicates<'tcx>(
98116}
99117
100118impl Elaborator < ' tcx > {
119+ pub fn filter_to_traits ( self ) -> FilterToTraits < Self > {
120+ FilterToTraits :: new ( self )
121+ }
122+
101123 fn elaborate ( & mut self , predicate : & ty:: Predicate < ' tcx > ) {
102124 let tcx = self . visited . tcx ;
103125 match * predicate {
@@ -223,3 +245,57 @@ impl Iterator for Elaborator<'tcx> {
223245 }
224246 }
225247}
248+
249+ ///////////////////////////////////////////////////////////////////////////
250+ // Supertrait iterator
251+ ///////////////////////////////////////////////////////////////////////////
252+
253+ pub type Supertraits < ' tcx > = FilterToTraits < Elaborator < ' tcx > > ;
254+
255+ pub fn supertraits < ' tcx > (
256+ tcx : TyCtxt < ' tcx > ,
257+ trait_ref : ty:: PolyTraitRef < ' tcx > ,
258+ ) -> Supertraits < ' tcx > {
259+ elaborate_trait_ref ( tcx, trait_ref) . filter_to_traits ( )
260+ }
261+
262+ pub fn transitive_bounds < ' tcx > (
263+ tcx : TyCtxt < ' tcx > ,
264+ bounds : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
265+ ) -> Supertraits < ' tcx > {
266+ elaborate_trait_refs ( tcx, bounds) . filter_to_traits ( )
267+ }
268+
269+ ///////////////////////////////////////////////////////////////////////////
270+ // Other
271+ ///////////////////////////////////////////////////////////////////////////
272+
273+ /// A filter around an iterator of predicates that makes it yield up
274+ /// just trait references.
275+ pub struct FilterToTraits < I > {
276+ base_iterator : I ,
277+ }
278+
279+ impl < I > FilterToTraits < I > {
280+ fn new ( base : I ) -> FilterToTraits < I > {
281+ FilterToTraits { base_iterator : base }
282+ }
283+ }
284+
285+ impl < ' tcx , I : Iterator < Item = ty:: Predicate < ' tcx > > > Iterator for FilterToTraits < I > {
286+ type Item = ty:: PolyTraitRef < ' tcx > ;
287+
288+ fn next ( & mut self ) -> Option < ty:: PolyTraitRef < ' tcx > > {
289+ while let Some ( pred) = self . base_iterator . next ( ) {
290+ if let ty:: Predicate :: Trait ( data, _) = pred {
291+ return Some ( data. to_poly_trait_ref ( ) ) ;
292+ }
293+ }
294+ None
295+ }
296+
297+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
298+ let ( _, upper) = self . base_iterator . size_hint ( ) ;
299+ ( 0 , upper)
300+ }
301+ }
0 commit comments