@@ -69,6 +69,7 @@ impl<'tcx> Extend<ty::Predicate<'tcx>> for PredicateSet<'tcx> {
6969pub  struct  Elaborator < ' tcx ,  O >  { 
7070    stack :  Vec < O > , 
7171    visited :  PredicateSet < ' tcx > , 
72+     only_self :  bool , 
7273} 
7374
7475/// Describes how to elaborate an obligation into a sub-obligation. 
@@ -170,7 +171,8 @@ pub fn elaborate<'tcx, O: Elaboratable<'tcx>>(
170171    tcx :  TyCtxt < ' tcx > , 
171172    obligations :  impl  IntoIterator < Item  = O > , 
172173)  -> Elaborator < ' tcx ,  O >  { 
173-     let  mut  elaborator = Elaborator  {  stack :  Vec :: new ( ) ,  visited :  PredicateSet :: new ( tcx)  } ; 
174+     let  mut  elaborator =
175+         Elaborator  {  stack :  Vec :: new ( ) ,  visited :  PredicateSet :: new ( tcx) ,  only_self :  false  } ; 
174176    elaborator. extend_deduped ( obligations) ; 
175177    elaborator
176178} 
@@ -185,14 +187,25 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
185187        self . stack . extend ( obligations. into_iter ( ) . filter ( |o| self . visited . insert ( o. predicate ( ) ) ) ) ; 
186188    } 
187189
190+     /// Filter to only the supertraits of trait predicates, i.e. only the predicates 
191+ /// that have `Self` as their self type, instead of all implied predicates. 
192+ pub  fn  filter_only_self ( mut  self )  -> Self  { 
193+         self . only_self  = true ; 
194+         self 
195+     } 
196+ 
188197    fn  elaborate ( & mut  self ,  elaboratable :  & O )  { 
189198        let  tcx = self . visited . tcx ; 
190199
191200        let  bound_predicate = elaboratable. predicate ( ) . kind ( ) ; 
192201        match  bound_predicate. skip_binder ( )  { 
193202            ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( data) )  => { 
194-                 // Get predicates declared on the trait. 
195-                 let  predicates = tcx. implied_predicates_of ( data. def_id ( ) ) ; 
203+                 // Get predicates implied by the trait, or only super predicates if we only care about self predicates. 
204+                 let  predicates = if  self . only_self  { 
205+                     tcx. super_predicates_of ( data. def_id ( ) ) 
206+                 }  else  { 
207+                     tcx. implied_predicates_of ( data. def_id ( ) ) 
208+                 } ; 
196209
197210                let  obligations =
198211                    predicates. predicates . iter ( ) . enumerate ( ) . map ( |( index,  & ( mut  pred,  span) ) | { 
@@ -350,18 +363,16 @@ pub fn supertraits<'tcx>(
350363    tcx :  TyCtxt < ' tcx > , 
351364    trait_ref :  ty:: PolyTraitRef < ' tcx > , 
352365)  -> impl  Iterator < Item  = ty:: PolyTraitRef < ' tcx > >  { 
353-     let  pred:  ty:: Predicate < ' tcx >  = trait_ref. to_predicate ( tcx) ; 
354-     FilterToTraits :: new ( elaborate ( tcx,  [ pred] ) ) 
366+     elaborate ( tcx,  [ trait_ref. to_predicate ( tcx) ] ) . filter_only_self ( ) . filter_to_traits ( ) 
355367} 
356368
357369pub  fn  transitive_bounds < ' tcx > ( 
358370    tcx :  TyCtxt < ' tcx > , 
359371    trait_refs :  impl  Iterator < Item  = ty:: PolyTraitRef < ' tcx > > , 
360372)  -> impl  Iterator < Item  = ty:: PolyTraitRef < ' tcx > >  { 
361-     FilterToTraits :: new ( elaborate ( 
362-         tcx, 
363-         trait_refs. map ( |trait_ref| -> ty:: Predicate < ' tcx >  {  trait_ref. to_predicate ( tcx)  } ) , 
364-     ) ) 
373+     elaborate ( tcx,  trait_refs. map ( |trait_ref| trait_ref. to_predicate ( tcx) ) ) 
374+         . filter_only_self ( ) 
375+         . filter_to_traits ( ) 
365376} 
366377
367378/// A specialized variant of `elaborate` that only elaborates trait references that may 
@@ -402,18 +413,18 @@ pub fn transitive_bounds_that_define_assoc_type<'tcx>(
402413// Other 
403414/////////////////////////////////////////////////////////////////////////// 
404415
416+ impl < ' tcx >  Elaborator < ' tcx ,  ty:: Predicate < ' tcx > >  { 
417+     fn  filter_to_traits ( self )  -> FilterToTraits < Self >  { 
418+         FilterToTraits  {  base_iterator :  self  } 
419+     } 
420+ } 
421+ 
405422/// A filter around an iterator of predicates that makes it yield up 
406423/// just trait references. 
407424pub  struct  FilterToTraits < I >  { 
408425    base_iterator :  I , 
409426} 
410427
411- impl < I >  FilterToTraits < I >  { 
412-     fn  new ( base :  I )  -> FilterToTraits < I >  { 
413-         FilterToTraits  {  base_iterator :  base } 
414-     } 
415- } 
416- 
417428impl < ' tcx ,  I :  Iterator < Item  = ty:: Predicate < ' tcx > > >  Iterator  for  FilterToTraits < I >  { 
418429    type  Item  = ty:: PolyTraitRef < ' tcx > ; 
419430
0 commit comments