@@ -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