Skip to content

Commit

Permalink
add test for inductive cycle hangs
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Dec 9, 2023
1 parent 608f324 commit e166c3e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
36 changes: 36 additions & 0 deletions tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs
Original file line number Diff line number Diff line change
@@ -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<?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 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<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
}
16 changes: 16 additions & 0 deletions tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
--> $DIR/inductive-fixpoint-hang.rs:30:19
|
LL | impls_trait::<W<_>>();
| ^^^^
|
= 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<T: Trait>() {}
| ^^^^^ required by this bound in `impls_trait`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.

0 comments on commit e166c3e

Please sign in to comment.