Open detrumi opened 2 years ago
Slightly simpler repro, this one from rust-lang/rust-analyzer#12667. Hangs even with default depth.
#[test]
fn ra_12667() {
test! {
program {
trait Clone { }
trait A {
type X: B;
}
trait B {
type Y: A<X = Self>;
}
}
goal {
exists<T> {
if (T: A) {
<T as A>::X: Clone
}
}
} yields[SolverChoice::recursive_default()] {
expect![["No possible solution"]]
}
}
}
So it's expanding the goals like this:
AliasEq(<(B::Y)<^0.0> as A>::X = ^0.1)
AliasEq(<(A::X)<(B::Y)<^0.0>> as B>::Y = ^0.1),
AliasEq(<(B::Y)<(A::X)<(B::Y)<^0.0>>> as A>::X = ^0.1)
which replaces <(B::Y)<^0.0>
with <(B::Y)<(A::X)<(B::Y)<^0.0>>>
, and then the solver just repeatedly expands the left side.
And because the goal keeps expanding, it's not triggering the cycle detection.
Do we need to start inspecting substitutions/goals for such repetitions, or is there a better solution?
I ran into another variant of this problem. The following code also hangs with rust-analyzer analysis-stats .
on the function outer
:
pub trait Foo {
type Bar: Bar<Foo = Self>;
}
pub trait Bar {
type Foo: Foo<Bar = Self>;
}
type Inner<A> = <<A as Foo>::Bar as Bar>::Foo;
fn inner<A: Foo>(val: Inner<A>) -> A {
val
}
fn outer<A: Foo>(val: Inner<A>) -> A {
let ret = inner(val);
ret
}
I think this is the same underlying problem, but I also wanted to share this variation to trigger the problem.
Found in rust-analyzer#12897, the following test causes the recursive solver to loop:
Output: