34 lines
1.2 KiB
Rust
34 lines
1.2 KiB
Rust
// 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
|
|
}
|