Anonymize late bound regions on transitive bounds that define assoc type

This commit is contained in:
Santiago Pastorino 2021-02-05 15:52:57 -03:00
parent fd092557ce
commit 8d17c6a85d
No known key found for this signature in database
GPG key ID: 8131A24E0C79EFAF
2 changed files with 54 additions and 14 deletions

View file

@ -292,26 +292,33 @@ pub fn transitive_bounds_that_define_assoc_type<'tcx>(
tcx: TyCtxt<'tcx>,
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
assoc_name: Ident,
) -> FxIndexSet<ty::PolyTraitRef<'tcx>> {
) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
let mut stack: Vec<_> = bounds.collect();
let mut trait_refs = FxIndexSet::default();
let mut visited = FxIndexSet::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.kind();
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);
std::iter::from_fn(move || {
while let Some(trait_ref) = stack.pop() {
let anon_trait_ref = tcx.anonymize_late_bound_regions(trait_ref);
if visited.insert(anon_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.kind();
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);
}
}
return Some(trait_ref);
}
}
}
trait_refs
return None;
})
}
///////////////////////////////////////////////////////////////////////////