You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of #792 - lowr:fix/generalize-alias-alias-eq-clause, r=jackh726
Generalize program clause for `AliasEq` goal with nested alias
Consider a goal: `AliasEq(<<?0 as X>::A as Y>::B = <<?1 as X>::A as Y>::B)`. This is expected to (eventually) flounder when the traits are non-enumerable and the variables are yet to be known, but it's currently **disproven**:
1. the goal is canonicalized as follows:
- `forall<T, U> AliasEq(<<T as X>::A as Y>::B = <<U as X>::A as Y>::B)`
1. we produce the following `ProgramClause` that could match:
- `forall<T, U, ..> AliasEq(<<T as X>::A as Y>::B = <<U as X>::A as Y>::B) :- AliasEq(..), AliasEq(..)`
1. the consequence of the (instantiated) clause is unified with the goal, which produces a subgoal:
- `AliasEq(<<?0 as X>::A as Y>::B = <<?1 as X>::A as Y>::B)`
- this is because when we unify rhs of `AliasEq`, we see two `AliasTy`s that we cannot unify structurally, forcing us to produce the subgoal
1. boom, cycle emerged, goal disproven!
The problem is that because we're reusing the original goal as the consequence of the program clause we expect them to unify structurally, however we cannot unify aliases structurally in general (e.g. `<?0 as X>::A = <?1 as X>::A` does not imply `?0 = ?1`).
This PR solves it by placing a fresh variable in rhs of the consequence `AliasEq` instead of reusing the original term. This ensures that rhs of the original `AliasEq` goal is preserved via unification without producing subgoals even if it's an alias.
See rust-lang/rust-analyzer#14369 for a real world case where this issue arises.
0 commit comments