Skip to content

Commit

Permalink
Inline elaborate_trait_refs_that_define_assoc_type into transitive_bo…
Browse files Browse the repository at this point in the history
…unds_that_define_assoc_type
  • Loading branch information
spastorino committed Nov 27, 2020
1 parent 9e0538b commit 28446ef
Showing 1 changed file with 24 additions and 32 deletions.
56 changes: 24 additions & 32 deletions compiler/rustc_infer/src/traits/util.rs
Expand Up @@ -90,37 +90,6 @@ pub fn elaborate_trait_refs<'tcx>(
elaborate_predicates(tcx, predicates)
}

/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
/// define the given associated type `assoc_name`. It uses the
/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
/// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
pub fn elaborate_trait_refs_that_define_assoc_type<'tcx>(
tcx: TyCtxt<'tcx>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
assoc_name: Ident,
) -> FxHashSet<ty::PolyTraitRef<'tcx>> {
let mut stack: Vec<_> = trait_refs.collect();
let mut trait_refs = FxHashSet::default();

while let Some(trait_ref) = stack.pop() {
if trait_refs.insert(trait_ref) {
let super_predicates =
tcx.super_predicates_that_define_assoc_type((trait_ref.def_id(), Some(assoc_name)));
for (super_predicate, _) in super_predicates.predicates {
let bound_predicate = super_predicate.bound_atom();
let subst_predicate = super_predicate
.subst_supertrait(tcx, &bound_predicate.rebind(trait_ref.skip_binder()));
if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
stack.push(binder.value);
}
}
}
}

trait_refs
}

pub fn elaborate_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
Expand Down Expand Up @@ -319,12 +288,35 @@ pub fn transitive_bounds<'tcx>(
elaborate_trait_refs(tcx, bounds).filter_to_traits()
}

/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
/// define the given associated type `assoc_name`. It uses the
/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
/// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
pub fn transitive_bounds_that_define_assoc_type<'tcx>(
tcx: TyCtxt<'tcx>,
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
assoc_name: Ident,
) -> FxHashSet<ty::PolyTraitRef<'tcx>> {
elaborate_trait_refs_that_define_assoc_type(tcx, bounds, assoc_name)
let mut stack: Vec<_> = bounds.collect();
let mut trait_refs = FxHashSet::default();

while let Some(trait_ref) = stack.pop() {
if trait_refs.insert(trait_ref) {
let super_predicates =
tcx.super_predicates_that_define_assoc_type((trait_ref.def_id(), Some(assoc_name)));
for (super_predicate, _) in super_predicates.predicates {
let bound_predicate = super_predicate.bound_atom();
let subst_predicate = super_predicate
.subst_supertrait(tcx, &bound_predicate.rebind(trait_ref.skip_binder()));
if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
stack.push(binder.value);
}
}
}
}

trait_refs
}

///////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 28446ef

Please sign in to comment.