about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2023-05-08 19:41:49 +0900
committerGitHub <noreply@github.com>2023-05-08 19:41:49 +0900
commitc145d933955b4c690768d5c526db671ab4d4d4b6 (patch)
treef47c50cd41681feb9803ec193a9aaafc95ed4f12
parent4df84a1e4e841045d4ff8a328d1054e4f02101c1 (diff)
parent930eece9d34b67533cf3d27c06253e806a5add0f (diff)
downloadrust-c145d933955b4c690768d5c526db671ab4d4d4b6.tar.gz
rust-c145d933955b4c690768d5c526db671ab4d4d4b6.zip
Rollup merge of #111211 - compiler-errors:negative-bounds-super, r=TaKO8Ki
Don't compute trait super bounds unless they're positive

Fixes #111207

The comment is modified to explain the rationale for why we even have this recursive call to supertraits in the first place, which doesn't apply to negative bounds since they don't elaborate at all.
-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
+