1
Fork 0

Split out transitive_bounds_that_define_assoc_item

This commit is contained in:
Michael Goulet 2024-07-05 16:02:35 -04:00
parent e5412da723
commit 99429a6a18

View file

@ -3,6 +3,7 @@ use smallvec::smallvec;
use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::infer::outlives::components::{push_outlives_components, Component};
use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::ToPolyTraitRef;
use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::Span; use rustc_span::Span;
@ -82,7 +83,6 @@ pub struct Elaborator<'tcx, O> {
enum Filter { enum Filter {
All, All,
OnlySelf, OnlySelf,
OnlySelfThatDefines(Ident),
} }
/// Describes how to elaborate an obligation into a sub-obligation. /// Describes how to elaborate an obligation into a sub-obligation.
@ -252,12 +252,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
self self
} }
/// Filter to only the supertraits of trait predicates that define the assoc_ty.
pub fn filter_only_self_that_defines(mut self, assoc_ty: Ident) -> Self {
self.mode = Filter::OnlySelfThatDefines(assoc_ty);
self
}
fn elaborate(&mut self, elaboratable: &O) { fn elaborate(&mut self, elaboratable: &O) {
let tcx = self.visited.tcx; let tcx = self.visited.tcx;
@ -277,9 +271,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
let predicates = match self.mode { let predicates = match self.mode {
Filter::All => tcx.explicit_implied_predicates_of(data.def_id()), Filter::All => tcx.explicit_implied_predicates_of(data.def_id()),
Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()), Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()),
Filter::OnlySelfThatDefines(ident) => {
tcx.explicit_supertraits_containing_assoc_item((data.def_id(), ident))
}
}; };
let obligations = let obligations =
@ -427,10 +418,30 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>, trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
assoc_name: Ident, assoc_name: Ident,
) -> FilterToTraits<Elaborator<'tcx, ty::Clause<'tcx>>> { ) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) let mut seen = FxHashSet::default();
.filter_only_self_that_defines(assoc_name) let mut stack: Vec<_> = trait_refs.collect();
.filter_to_traits()
std::iter::from_fn(move || {
while let Some(trait_ref) = stack.pop() {
if !seen.insert(tcx.anonymize_bound_vars(trait_ref)) {
continue;
}
stack.extend(
tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name))
.instantiate_own_identity()
.map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref))
.filter_map(|clause| clause.as_trait_clause())
// FIXME: Negative supertraits are elaborated here lol
.map(|trait_pred| trait_pred.to_poly_trait_ref()),
);
return Some(trait_ref);
}
None
})
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////