Skip to content

Commit 99429a6

Browse files
Split out transitive_bounds_that_define_assoc_item
1 parent e5412da commit 99429a6

File tree

1 file changed

+25
-14
lines changed
  • compiler/rustc_infer/src/traits

1 file changed

+25
-14
lines changed

compiler/rustc_infer/src/traits/util.rs

+25-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use smallvec::smallvec;
33
use crate::infer::outlives::components::{push_outlives_components, Component};
44
use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation};
55
use rustc_data_structures::fx::FxHashSet;
6+
use rustc_middle::ty::ToPolyTraitRef;
67
use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
78
use rustc_span::symbol::Ident;
89
use rustc_span::Span;
@@ -82,7 +83,6 @@ pub struct Elaborator<'tcx, O> {
8283
enum 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 =
@@ -427,10 +418,30 @@ 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::Clause<'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
///////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)