@@ -3,6 +3,7 @@ use smallvec::smallvec;
33use crate :: infer:: outlives:: components:: { push_outlives_components, Component } ;
44use crate :: traits:: { self , Obligation , ObligationCauseCode , PredicateObligation } ;
55use rustc_data_structures:: fx:: FxHashSet ;
6+ use rustc_middle:: ty:: ToPolyTraitRef ;
67use rustc_middle:: ty:: { self , Ty , TyCtxt , Upcast } ;
78use rustc_span:: symbol:: Ident ;
89use rustc_span:: Span ;
@@ -82,7 +83,6 @@ pub struct Elaborator<'tcx, O> {
8283enum Filter {
8384 All ,
8485 OnlySelf ,
85- OnlySelfThatDefines ( Ident ) ,
8686}
8787
8888/// Describes how to elaborate an obligation into a sub-obligation.
@@ -252,12 +252,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
252252 self
253253 }
254254
255- /// Filter to only the supertraits of trait predicates that define the assoc_ty.
256- pub fn filter_only_self_that_defines ( mut self , assoc_ty : Ident ) -> Self {
257- self . mode = Filter :: OnlySelfThatDefines ( assoc_ty) ;
258- self
259- }
260-
261255 fn elaborate ( & mut self , elaboratable : & O ) {
262256 let tcx = self . visited . tcx ;
263257
@@ -277,9 +271,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
277271 let predicates = match self . mode {
278272 Filter :: All => tcx. explicit_implied_predicates_of ( data. def_id ( ) ) ,
279273 Filter :: OnlySelf => tcx. explicit_super_predicates_of ( data. def_id ( ) ) ,
280- Filter :: OnlySelfThatDefines ( ident) => {
281- tcx. explicit_supertraits_containing_assoc_item ( ( data. def_id ( ) , ident) )
282- }
283274 } ;
284275
285276 let obligations =
@@ -405,14 +396,14 @@ impl<'tcx, O: Elaboratable<'tcx>> Iterator for Elaborator<'tcx, O> {
405396pub fn supertraits < ' tcx > (
406397 tcx : TyCtxt < ' tcx > ,
407398 trait_ref : ty:: PolyTraitRef < ' tcx > ,
408- ) -> FilterToTraits < Elaborator < ' tcx , ty:: Predicate < ' tcx > > > {
399+ ) -> FilterToTraits < Elaborator < ' tcx , ty:: Clause < ' tcx > > > {
409400 elaborate ( tcx, [ trait_ref. upcast ( tcx) ] ) . filter_only_self ( ) . filter_to_traits ( )
410401}
411402
412403pub fn transitive_bounds < ' tcx > (
413404 tcx : TyCtxt < ' tcx > ,
414405 trait_refs : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
415- ) -> FilterToTraits < Elaborator < ' tcx , ty:: Predicate < ' tcx > > > {
406+ ) -> FilterToTraits < Elaborator < ' tcx , ty:: Clause < ' tcx > > > {
416407 elaborate ( tcx, trait_refs. map ( |trait_ref| trait_ref. upcast ( tcx) ) )
417408 . filter_only_self ( )
418409 . filter_to_traits ( )
@@ -427,17 +418,37 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
427418 tcx : TyCtxt < ' tcx > ,
428419 trait_refs : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
429420 assoc_name : Ident ,
430- ) -> FilterToTraits < Elaborator < ' tcx , ty:: Predicate < ' tcx > > > {
431- elaborate ( tcx, trait_refs. map ( |trait_ref| trait_ref. upcast ( tcx) ) )
432- . filter_only_self_that_defines ( assoc_name)
433- . filter_to_traits ( )
421+ ) -> impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > {
422+ let mut seen = FxHashSet :: default ( ) ;
423+ let mut stack: Vec < _ > = trait_refs. collect ( ) ;
424+
425+ std:: iter:: from_fn ( move || {
426+ while let Some ( trait_ref) = stack. pop ( ) {
427+ if !seen. insert ( tcx. anonymize_bound_vars ( trait_ref) ) {
428+ continue ;
429+ }
430+
431+ stack. extend (
432+ tcx. explicit_supertraits_containing_assoc_item ( ( trait_ref. def_id ( ) , assoc_name) )
433+ . instantiate_own_identity ( )
434+ . map ( |( clause, _) | clause. instantiate_supertrait ( tcx, trait_ref) )
435+ . filter_map ( |clause| clause. as_trait_clause ( ) )
436+ // FIXME: Negative supertraits are elaborated here lol
437+ . map ( |trait_pred| trait_pred. to_poly_trait_ref ( ) ) ,
438+ ) ;
439+
440+ return Some ( trait_ref) ;
441+ }
442+
443+ None
444+ } )
434445}
435446
436447///////////////////////////////////////////////////////////////////////////
437448// Other
438449///////////////////////////////////////////////////////////////////////////
439450
440- impl < ' tcx > Elaborator < ' tcx , ty:: Predicate < ' tcx > > {
451+ impl < ' tcx > Elaborator < ' tcx , ty:: Clause < ' tcx > > {
441452 fn filter_to_traits ( self ) -> FilterToTraits < Self > {
442453 FilterToTraits { base_iterator : self }
443454 }
@@ -449,7 +460,7 @@ pub struct FilterToTraits<I> {
449460 base_iterator : I ,
450461}
451462
452- impl < ' tcx , I : Iterator < Item = ty:: Predicate < ' tcx > > > Iterator for FilterToTraits < I > {
463+ impl < ' tcx , I : Iterator < Item = ty:: Clause < ' tcx > > > Iterator for FilterToTraits < I > {
453464 type Item = ty:: PolyTraitRef < ' tcx > ;
454465
455466 fn next ( & mut self ) -> Option < ty:: PolyTraitRef < ' tcx > > {
0 commit comments