From e166c3eb213716f94ff860ccdbaac01c1ca95e61 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 9 Dec 2023 09:47:14 +0000 Subject: [PATCH] add test for inductive cycle hangs --- .../cycles/inductive-fixpoint-hang.rs | 36 +++++++++++++++++++ .../cycles/inductive-fixpoint-hang.stderr | 16 +++++++++ 2 files changed, 52 insertions(+) create mode 100644 tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs create mode 100644 tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs new file mode 100644 index 0000000000000..16fb0db665109 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs @@ -0,0 +1,36 @@ +// compile-flags: -Ztrait-solver=next + +// This currently hangs if we do not erase constraints from +// overflow. +// +// We set the provisional result of `W` to `?0 := W<_>`. +// The next iteration does not simply result in a `?0 := W` constraint as +// one might expect, but instead each time we evaluate the nested `W` goal we +// apply the previously returned constraints: the first fixpoint iteration goes +// as follows: `W: Trait` constrains `?1` to `W`, we then evaluate +// `W>: Trait` the next time we try to prove the nested goal. This results +// inn `W>>` 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>>` with a size proportional +// to the number of steps in `try_evaluate_added_goals`. The size then continues +// to grow until evaluating the nested goals ends up hitting the recursion limit. +// +// By then the exponential blowup from having 2 nested goals per impl causes +// the solver to hang. In this concrete example a provisional cache should prevent +// the hang. +trait Trait {} + +struct W(*const T); + +impl Trait for W> +where + W: Trait, + W: Trait, +{} + +fn impls_trait() {} + +fn main() { + impls_trait::>(); + //~^ ERROR overflow evaluating the requirement +} diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr new file mode 100644 index 0000000000000..4953cda8568ab --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr @@ -0,0 +1,16 @@ +error[E0275]: overflow evaluating the requirement `W<_>: Trait` + --> $DIR/inductive-fixpoint-hang.rs:30:19 + | +LL | impls_trait::>(); + | ^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_fixpoint_hang`) +note: required by a bound in `impls_trait` + --> $DIR/inductive-fixpoint-hang.rs:27:19 + | +LL | fn impls_trait() {} + | ^^^^^ required by this bound in `impls_trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`.