about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs11
-rw-r--r--tests/ui/traits/negative-bounds/supertrait.rs9
-rw-r--r--tests/ui/traits/negative-bounds/supertrait.stderr10
3 files changed, 25 insertions, 5 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 6c06957d1ee..e04658c8e77 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -657,14 +657,15 @@ pub(super) fn implied_predicates_with_filter(
         &*tcx.arena.alloc_from_iter(superbounds.predicates().chain(where_bounds_that_match));
     debug!(?implied_bounds);
 
-    // Now require that immediate supertraits are converted,
-    // which will, in turn, reach indirect supertraits.
+    // 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) {
-        // Now require that immediate supertraits are converted,
-        // which will, in turn, reach indirect supertraits.
         for &(pred, span) in implied_bounds {
             debug!("superbound: {:?}", pred);
-            if let ty::PredicateKind::Clause(ty::Clause::Trait(bound)) = pred.kind().skip_binder() {
+            if let ty::PredicateKind::Clause(ty::Clause::Trait(bound)) = pred.kind().skip_binder()
+                && bound.polarity == ty::ImplPolarity::Positive
+            {
                 tcx.at(span).super_predicates_of(bound.def_id());
             }
         }
diff --git a/tests/ui/traits/negative-bounds/supertrait.rs b/tests/ui/traits/negative-bounds/supertrait.rs
new file mode 100644
index 00000000000..df0884b8b9f
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/supertrait.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(negative_bounds)]
+//~^ WARN the feature `negative_bounds` is incomplete
+
+trait A: !B {}
+trait B: !A {}
+
+fn main() {}
diff --git a/tests/ui/traits/negative-bounds/supertrait.stderr b/tests/ui/traits/negative-bounds/supertrait.stderr
new file mode 100644
index 00000000000..f44753b624e
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/supertrait.stderr
@@ -0,0 +1,10 @@
+warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/supertrait.rs:3:12
+   |
+LL | #![feature(negative_bounds)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+