diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2021-02-05 15:52:57 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2021-02-08 16:47:51 -0300 |
| commit | 8d17c6a85d6530d446d1cb42ee6636c5c9fbfaaf (patch) | |
| tree | be308f5a8f6f0cc0b2974dd38c16fcf198b86d52 | |
| parent | fd092557ceb36998dc93aa46a797745c58f1969f (diff) | |
| download | rust-8d17c6a85d6530d446d1cb42ee6636c5c9fbfaaf.tar.gz rust-8d17c6a85d6530d446d1cb42ee6636c5c9fbfaaf.zip | |
Anonymize late bound regions on transitive bounds that define assoc type
| -rw-r--r-- | compiler/rustc_infer/src/traits/util.rs | 37 | ||||
| -rw-r--r-- | src/test/ui/associated-type-bounds/traits-assoc-anonymized.rs | 33 |
2 files changed, 55 insertions, 15 deletions
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 8a1035707fe..87684c2715f 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -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(); - - 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); + let mut visited = FxIndexSet::default(); + + 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; + }) } /////////////////////////////////////////////////////////////////////////// diff --git a/src/test/ui/associated-type-bounds/traits-assoc-anonymized.rs b/src/test/ui/associated-type-bounds/traits-assoc-anonymized.rs new file mode 100644 index 00000000000..a9d6eed810a --- /dev/null +++ b/src/test/ui/associated-type-bounds/traits-assoc-anonymized.rs @@ -0,0 +1,33 @@ +// check-pass + +pub struct LookupInternedStorage; + +impl<Q> QueryStorageOps<Q> for LookupInternedStorage +where + Q: Query, + for<'d> Q: QueryDb<'d>, +{ + fn fmt_index(&self, db: &<Q as QueryDb<'_>>::DynDb) { + <<Q as QueryDb<'_>>::DynDb as HasQueryGroup<Q::Group>>::group_storage(db); + } +} + +pub trait HasQueryGroup<G> { + fn group_storage(&self); +} + +pub trait QueryStorageOps<Q> +where + Q: Query, +{ + fn fmt_index(&self, db: &<Q as QueryDb<'_>>::DynDb); +} + +pub trait QueryDb<'d> { + type DynDb: HasQueryGroup<Self::Group> + 'd; + type Group; +} + +pub trait Query: for<'d> QueryDb<'d> {} + +fn main() {} |
