summaryrefslogtreecommitdiffstats
path: root/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs')
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs
new file mode 100644
index 000000000..efeb8d023
--- /dev/null
+++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs
@@ -0,0 +1,33 @@
+// compile-flags: -Znext-solver
+
+// This currently hangs if we do not erase constraints from
+// overflow.
+//
+// We set the provisional result of `W<?0>` to `?0 := W<_>`.
+// The next iteration does not simply result in a `?0 := W<W<_>` constraint as
+// one might expect, but instead each time we evaluate the nested `W<T>` goal we
+// apply the previously returned constraints: the first fixpoint iteration goes
+// as follows: `W<?1>: Trait` constrains `?1` to `W<?2>`, we then evaluate
+// `W<W<?2>>: Trait` the next time we try to prove the nested goal. This results
+// inn `W<W<W<?3>>>` and so on. This goes on until we reach overflow in
+// `try_evaluate_added_goals`. This means the provisional result after the
+// second fixpoint iteration is already `W<W<W<...>>>` with a size proportional
+// to the number of steps in `try_evaluate_added_goals`. The size then continues
+// to grow. The exponential blowup from having 2 nested goals per impl causes
+// the solver to hang without hitting the recursion limit.
+trait Trait {}
+
+struct W<T: ?Sized>(*const T);
+
+impl<T: ?Sized> Trait for W<W<T>>
+where
+ W<T>: Trait,
+ W<T>: Trait,
+{}
+
+fn impls_trait<T: Trait>() {}
+
+fn main() {
+ impls_trait::<W<_>>();
+ //~^ ERROR overflow evaluating the requirement
+}