about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2021-02-05 15:52:57 -0300
committerSantiago Pastorino <spastorino@gmail.com>2021-02-08 16:47:51 -0300
commit8d17c6a85d6530d446d1cb42ee6636c5c9fbfaaf (patch)
treebe308f5a8f6f0cc0b2974dd38c16fcf198b86d52
parentfd092557ceb36998dc93aa46a797745c58f1969f (diff)
downloadrust-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.rs37
-rw-r--r--src/test/ui/associated-type-bounds/traits-assoc-anonymized.rs33
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() {}