mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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. Fixes <rdar://problem/83894546>.
34 lines
774 B
Swift
34 lines
774 B
Swift
// RUN: %target-typecheck-verify-swift
|
|
|
|
public protocol P1 {
|
|
associatedtype A: P1 where A.A == A
|
|
}
|
|
|
|
public protocol P2 {
|
|
associatedtype B: P1
|
|
associatedtype C: P2
|
|
}
|
|
|
|
public struct G<B : P1> : P2 {
|
|
public typealias C = G<B.A>
|
|
}
|
|
|
|
// C == G<B> together with the definition of G<B>.C implies an infinite series
|
|
// of rules:
|
|
// - C.C == G<B.A>
|
|
// - C.C.C == G<B.A.A>
|
|
// - C.C.C.C == G<B.A.A.A>
|
|
// - ...
|
|
//
|
|
// 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:
|
|
//
|
|
// - C.C == G<B.A>
|
|
// - C.C.C == B<G.A>
|
|
// - C.C.C.C == G<B.A>
|
|
// - ...
|
|
//
|
|
// Therefore, the single rule C.C == C.C.C suffices to "tie off" the recursion.
|
|
public protocol P3: P2 where C == G<B> {}
|