RequirementMachine: Tighten up type witness recursion hack #39673
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When a type parameter is subject to a conformance requirement and a concrete type requirement, the concrete type unification pass recursively walks each nested type introduced by the conformance requirement, and fixes it to the concrete type witness in the concrete type conformance.
In general, this can produce an infinite sequence of concrete type requirements. There are a couple of heuristics to "tie off" the recursion.
One heuristic is that if a nested type of a concrete parent type is exactly equal to the parent type, a same-type requirement is introduced between the child and the parent, preventing concrete type unification from recursing further.
This used to check for exact equality of types, but it is possible for the type witness to be equal under canonical type equivalence, but use a different spelling via same-type requirements for some type parameter appearing in structural position.
Instead, canonicalize terms here, allowing recursion where the type witness names a different spelling of the same type.
Here is an example:
The requirement
C == G<B>
in protocol P3 together with the definition ofG<B>.C
implies an infinite series of rules:This would normally prevent the completion procedure from terminating, however
A.A == A
in protocol P1 means that the right hand sides simplify as follows:Therefore, the single rule
C.C == C.C.C
suffices to "tie off" the recursion.Fixes rdar://problem/83894546.