Files
swift-mirror/test/SILGen/existential_erasure_length_2.swift
Slava Pestov d2b0bf002a AST: Fix existential erasure of long member types
Suppose protocol P has a primary associated type A, and we have
a `any P<S>` value. We form the generalization signature <T>
with substitution map {T := S}, and the existential signature
<T, Self where T == Self.A>.

Now, if we call a protocol requirement that takes Self.A.A.A,
we see this is fixed concrete type, because the reduced type of
Self.A.A.A is T.A.A in the existential signature.

However, this type parameter is not formed from the
conformance requirements of the generalization signature
(there aren't any), so we cannot directly apply the outer
substitution map.

Instead, change the outer substitution conformance lookup
callback to check if the reduced type parameter is valid
in the generalization signature, and not just rooted in a
generic parameter of the generalization signature.

If it isn't, fall back to global conformance lookup.

A better fix would introduce new requirements into the
generalization signature to handle this, or store them
separately in the generic environment itself. But this is fine
for now.

- Fixes https://github.com/swiftlang/swift/issues/79763.
- Fixes rdar://problem/146111083.
2025-04-29 18:58:58 -04:00

26 lines
410 B
Swift

// RUN: %target-swift-emit-silgen %s
protocol N {
associatedtype A: N
}
protocol P<A> {
associatedtype A: N
associatedtype B
func f0(_: A) -> B
func f1(_: A.A) -> B
func f2(_: A.A.A) -> B
}
struct G<T>: N {
typealias A = G<G<T>>
}
func call(x: any P<G<Int>>) -> (Any, Any, Any) {
let y0 = x.f0(G<Int>())
let y1 = x.f1(G<G<Int>>())
let y2 = x.f2(G<G<G<Int>>>())
return (y0, y1, y2)
}