@@ -3,7 +3,7 @@ use smallvec::smallvec;
3
3
use crate :: infer:: outlives:: components:: { push_outlives_components, Component } ;
4
4
use crate :: traits:: { Obligation , ObligationCause , PredicateObligation } ;
5
5
use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
6
- use rustc_middle:: ty:: { self , ToPredicate , TyCtxt } ;
6
+ use rustc_middle:: ty:: { self , ToPredicate , Ty , TyCtxt } ;
7
7
use rustc_span:: symbol:: Ident ;
8
8
use rustc_span:: Span ;
9
9
@@ -132,8 +132,11 @@ fn predicate_obligation<'tcx>(
132
132
}
133
133
134
134
impl < ' tcx > Elaborator < ' tcx > {
135
- pub fn filter_to_traits ( self ) -> FilterToTraits < Self > {
136
- FilterToTraits :: new ( self )
135
+ pub fn filter_to_traits (
136
+ self ,
137
+ filter_self_ty : Option < ty:: Binder < ' tcx , Ty < ' tcx > > > ,
138
+ ) -> FilterToTraits < ' tcx , Self > {
139
+ FilterToTraits :: new ( self , filter_self_ty)
137
140
}
138
141
139
142
fn elaborate ( & mut self , obligation : & PredicateObligation < ' tcx > ) {
@@ -312,20 +315,20 @@ impl<'tcx> Iterator for Elaborator<'tcx> {
312
315
// Supertrait iterator
313
316
///////////////////////////////////////////////////////////////////////////
314
317
315
- pub type Supertraits < ' tcx > = FilterToTraits < Elaborator < ' tcx > > ;
318
+ pub type Supertraits < ' tcx > = FilterToTraits < ' tcx , Elaborator < ' tcx > > ;
316
319
317
320
pub fn supertraits < ' tcx > (
318
321
tcx : TyCtxt < ' tcx > ,
319
322
trait_ref : ty:: PolyTraitRef < ' tcx > ,
320
323
) -> Supertraits < ' tcx > {
321
- elaborate_trait_ref ( tcx, trait_ref) . filter_to_traits ( )
324
+ elaborate_trait_ref ( tcx, trait_ref) . filter_to_traits ( Some ( trait_ref . self_ty ( ) ) )
322
325
}
323
326
324
327
pub fn transitive_bounds < ' tcx > (
325
328
tcx : TyCtxt < ' tcx > ,
326
329
bounds : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
327
330
) -> Supertraits < ' tcx > {
328
- elaborate_trait_refs ( tcx, bounds) . filter_to_traits ( )
331
+ elaborate_trait_refs ( tcx, bounds) . filter_to_traits ( None )
329
332
}
330
333
331
334
/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
@@ -370,22 +373,29 @@ pub fn transitive_bounds_that_define_assoc_type<'tcx>(
370
373
371
374
/// A filter around an iterator of predicates that makes it yield up
372
375
/// just trait references.
373
- pub struct FilterToTraits < I > {
376
+ pub struct FilterToTraits < ' tcx , I > {
374
377
base_iterator : I ,
378
+ filter_self_ty : Option < ty:: Binder < ' tcx , Ty < ' tcx > > > ,
375
379
}
376
380
377
- impl < I > FilterToTraits < I > {
378
- fn new ( base : I ) -> FilterToTraits < I > {
379
- FilterToTraits { base_iterator : base }
381
+ impl < ' tcx , I > FilterToTraits < ' tcx , I > {
382
+ fn new ( base : I , filter_self_ty : Option < ty :: Binder < ' tcx , Ty < ' tcx > > > ) -> FilterToTraits < ' tcx , I > {
383
+ FilterToTraits { base_iterator : base, filter_self_ty }
380
384
}
381
385
}
382
386
383
- impl < ' tcx , I : Iterator < Item = PredicateObligation < ' tcx > > > Iterator for FilterToTraits < I > {
387
+ impl < ' tcx , I : Iterator < Item = PredicateObligation < ' tcx > > > Iterator for FilterToTraits < ' tcx , I > {
384
388
type Item = ty:: PolyTraitRef < ' tcx > ;
385
389
386
390
fn next ( & mut self ) -> Option < ty:: PolyTraitRef < ' tcx > > {
387
391
while let Some ( obligation) = self . base_iterator . next ( ) {
388
- if let Some ( data) = obligation. predicate . to_opt_poly_trait_pred ( ) {
392
+ if let Some ( data) = obligation. predicate . to_opt_poly_trait_pred ( )
393
+ // A note on binders: Elaboration means that the output predicates
394
+ // may have more bound variables than the inputs. However, since we
395
+ // only append variables to the bound vars list, it is fine to
396
+ // compare self types outside of the binders.
397
+ && self . filter_self_ty . map_or ( true , |filter_self_ty| filter_self_ty. skip_binder ( ) == data. skip_binder ( ) . self_ty ( ) )
398
+ {
389
399
return Some ( data. map_bound ( |t| t. trait_ref ) ) ;
390
400
}
391
401
}
0 commit comments