@@ -69,6 +69,7 @@ impl<'tcx> Extend<ty::Predicate<'tcx>> for PredicateSet<'tcx> {
69
69
pub struct Elaborator < ' tcx , O > {
70
70
stack : Vec < O > ,
71
71
visited : PredicateSet < ' tcx > ,
72
+ only_self : bool ,
72
73
}
73
74
74
75
/// Describes how to elaborate an obligation into a sub-obligation.
@@ -170,7 +171,8 @@ pub fn elaborate<'tcx, O: Elaboratable<'tcx>>(
170
171
tcx : TyCtxt < ' tcx > ,
171
172
obligations : impl IntoIterator < Item = O > ,
172
173
) -> 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 } ;
174
176
elaborator. extend_deduped ( obligations) ;
175
177
elaborator
176
178
}
@@ -185,14 +187,25 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
185
187
self . stack . extend ( obligations. into_iter ( ) . filter ( |o| self . visited . insert ( o. predicate ( ) ) ) ) ;
186
188
}
187
189
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
+
188
197
fn elaborate ( & mut self , elaboratable : & O ) {
189
198
let tcx = self . visited . tcx ;
190
199
191
200
let bound_predicate = elaboratable. predicate ( ) . kind ( ) ;
192
201
match bound_predicate. skip_binder ( ) {
193
202
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
+ } ;
196
209
197
210
let obligations =
198
211
predicates. predicates . iter ( ) . enumerate ( ) . map ( |( index, & ( mut pred, span) ) | {
@@ -350,18 +363,16 @@ pub fn supertraits<'tcx>(
350
363
tcx : TyCtxt < ' tcx > ,
351
364
trait_ref : ty:: PolyTraitRef < ' tcx > ,
352
365
) -> 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 ( )
355
367
}
356
368
357
369
pub fn transitive_bounds < ' tcx > (
358
370
tcx : TyCtxt < ' tcx > ,
359
371
trait_refs : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
360
372
) -> 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 ( )
365
376
}
366
377
367
378
/// 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>(
402
413
// Other
403
414
///////////////////////////////////////////////////////////////////////////
404
415
416
+ impl < ' tcx > Elaborator < ' tcx , ty:: Predicate < ' tcx > > {
417
+ fn filter_to_traits ( self ) -> FilterToTraits < Self > {
418
+ FilterToTraits { base_iterator : self }
419
+ }
420
+ }
421
+
405
422
/// A filter around an iterator of predicates that makes it yield up
406
423
/// just trait references.
407
424
pub struct FilterToTraits < I > {
408
425
base_iterator : I ,
409
426
}
410
427
411
- impl < I > FilterToTraits < I > {
412
- fn new ( base : I ) -> FilterToTraits < I > {
413
- FilterToTraits { base_iterator : base }
414
- }
415
- }
416
-
417
428
impl < ' tcx , I : Iterator < Item = ty:: Predicate < ' tcx > > > Iterator for FilterToTraits < I > {
418
429
type Item = ty:: PolyTraitRef < ' tcx > ;
419
430
0 commit comments