about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-02-20 19:35:40 +0100
committerGitHub <noreply@github.com>2024-02-20 19:35:40 +0100
commitd43fd29bf2d0133b729d2c2187d195915b8cacfd (patch)
treef39c9a2eb7c5e15b76b90281f48d82cc20ae377b
parent3099a7931ab6b04874b5d8b9bcabddd5478cf4cf (diff)
parent994d55158dcfe0b1b299591bb552af14c63c6e60 (diff)
downloadrust-d43fd29bf2d0133b729d2c2187d195915b8cacfd.tar.gz
rust-d43fd29bf2d0133b729d2c2187d195915b8cacfd.zip
Rollup merge of #121322 - compiler-errors:next-solver-fulfillment-ice, r=lcnr
Don't ICE when hitting overflow limit in fulfillment loop in next solver

As the title says, let's not ICE when hitting the overflow limit in fulfill. On the other hand, we don't want to treat these as true errors, since it means that whether something is considered a true error or an ambiguity is dependent on overflow handling in the solver, which seems not worth it.

Now that we use the presence of true errors in fulfillment for implicit negative coherence, we especially don't want to tie together coherence and overflow.

I guess I could also drain these errors out of fulfillment and put them into some `ambiguities` storage so we could return them in `select_all_or_error` without having to re-process them every time we call `select_where_possible`. Let me know if that's desired.

r? lcnr
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs5
-rw-r--r--tests/ui/traits/next-solver/coherence-fulfill-overflow.rs15
-rw-r--r--tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr11
3 files changed, 30 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 63555a305d8..97f715b6386 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -109,7 +109,10 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
         let mut errors = Vec::new();
         for i in 0.. {
             if !infcx.tcx.recursion_limit().value_within_limit(i) {
-                unimplemented!("overflowed on pending obligations: {:?}", self.obligations);
+                // Only return true errors that we have accumulated while processing;
+                // keep ambiguities around, *including overflows*, because they shouldn't
+                // be considered true errors.
+                return errors;
             }
 
             let mut has_changed = false;
diff --git a/tests/ui/traits/next-solver/coherence-fulfill-overflow.rs b/tests/ui/traits/next-solver/coherence-fulfill-overflow.rs
new file mode 100644
index 00000000000..ff577da32c2
--- /dev/null
+++ b/tests/ui/traits/next-solver/coherence-fulfill-overflow.rs
@@ -0,0 +1,15 @@
+//@ compile-flags: -Znext-solver=coherence
+
+#![recursion_limit = "10"]
+
+trait Trait {}
+
+struct W<T: ?Sized>(*const T);
+trait TwoW {}
+impl<T: ?Sized + TwoW> TwoW for W<W<T>> {}
+
+impl<T: ?Sized + TwoW> Trait for W<T> {}
+impl<T: ?Sized + TwoW> Trait for T {}
+//~^ ERROR conflicting implementations of trait `Trait` for type `W
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr
new file mode 100644
index 00000000000..406c0ccca97
--- /dev/null
+++ b/tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
+  --> $DIR/coherence-fulfill-overflow.rs:12:1
+   |
+LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
+   | ------------------------------------- first implementation here
+LL | impl<T: ?Sized + TwoW> Trait for T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.