about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs30
-rw-r--r--tests/ui/associated-type-bounds/implied-bounds-cycle.rs10
-rw-r--r--tests/ui/associated-type-bounds/implied-bounds-cycle.stderr17
3 files changed, 49 insertions, 8 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 351ac2eb770..f70bb8c4289 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -640,16 +640,30 @@ pub(super) fn implied_predicates_with_filter(
 
     // Now require that immediate supertraits are converted, which will, in
     // turn, reach indirect supertraits, so we detect cycles now instead of
-    // overflowing during elaboration.
-    if matches!(filter, PredicateFilter::SelfOnly) {
-        for &(pred, span) in implied_bounds {
-            debug!("superbound: {:?}", pred);
-            if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
-                && bound.polarity == ty::ImplPolarity::Positive
-            {
-                tcx.at(span).super_predicates_of(bound.def_id());
+    // overflowing during elaboration. Same for implied predicates, which
+    // make sure we walk into associated type bounds.
+    match filter {
+        PredicateFilter::SelfOnly => {
+            for &(pred, span) in implied_bounds {
+                debug!("superbound: {:?}", pred);
+                if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
+                    && bound.polarity == ty::ImplPolarity::Positive
+                {
+                    tcx.at(span).super_predicates_of(bound.def_id());
+                }
+            }
+        }
+        PredicateFilter::SelfAndAssociatedTypeBounds => {
+            for &(pred, span) in implied_bounds {
+                debug!("superbound: {:?}", pred);
+                if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
+                    && bound.polarity == ty::ImplPolarity::Positive
+                {
+                    tcx.at(span).implied_predicates_of(bound.def_id());
+                }
             }
         }
+        _ => {}
     }
 
     ty::GenericPredicates { parent: None, predicates: implied_bounds }
diff --git a/tests/ui/associated-type-bounds/implied-bounds-cycle.rs b/tests/ui/associated-type-bounds/implied-bounds-cycle.rs
new file mode 100644
index 00000000000..785d47d4791
--- /dev/null
+++ b/tests/ui/associated-type-bounds/implied-bounds-cycle.rs
@@ -0,0 +1,10 @@
+#![feature(associated_type_bounds)]
+
+trait A {
+    type T;
+}
+
+trait B: A<T: B> {}
+//~^ ERROR cycle detected when computing the implied predicates of `B`
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/implied-bounds-cycle.stderr b/tests/ui/associated-type-bounds/implied-bounds-cycle.stderr
new file mode 100644
index 00000000000..1c1c64ea5f5
--- /dev/null
+++ b/tests/ui/associated-type-bounds/implied-bounds-cycle.stderr
@@ -0,0 +1,17 @@
+error[E0391]: cycle detected when computing the implied predicates of `B`
+  --> $DIR/implied-bounds-cycle.rs:7:15
+   |
+LL | trait B: A<T: B> {}
+   |               ^
+   |
+   = note: ...which immediately requires computing the implied predicates of `B` again
+note: cycle used when computing normalized predicates of `B`
+  --> $DIR/implied-bounds-cycle.rs:7:1
+   |
+LL | trait B: A<T: B> {}
+   | ^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0391`.