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