mirror of
https://github.com/apple/swift.git
synced 2026-10-06 12:37:28 +02:00
Fix a regression where an identity key path whose root type is formed by
expanding a single-element parameter pack fails to type-check in Swift 6
mode. The following code produced a conversion error between two
identically printed `KeyPath<Result<Post, any Error>, Result<Post, any
Error>>` types:
```swift
struct FormActionPost<each Value> {
func get<T>(
_ keyPath: KeyPath<
(repeat Result<each Value, any Error>),
Result<T, any Error>
>,
_ name: String
) throws -> T {
fatalError()
}
}
struct Post {}
func process(_ post: FormActionPost<Post>) throws -> Post {
try post.get(\.self, "fields")
}
```
This regression was introduced by 6a2784f87a in #87908. Previously, the
solver could first bind the root type variable of an identity key path
to a tuple containing an unresolved pack expansion. The pack would then
be resolved, allowing type checking to succeed. That change defers
bindings to one-element tuples whose element is an unresolved type
variable, changing the inference order. As a result, the solver compares
the key path against its contextual type while the pack is still
unresolved, exposing an existing gap in `matchTypes`.
The root and value of an identity key path share the same type variable.
When matching against the contextual root type, this variable is bound
to a tuple containing an unresolved pack expansion. During the
subsequent value-type comparison, the original type is a type variable,
but its fixed type is a tuple. Since `matchTypes` checked only the
original types, it missed the tuple matching needed to handle this case.
Check both the original and fixed types with
`isTupleWithUnresolvedPackExpansion`. This allows the existing tuple
matching logic to resolve the pack constraints.
Validation:
- Added regression coverage for Swift 6, Swift 5, and Swift 5 with
`InferSendableFromCaptures`, including the original reproducer, generic,
empty, and multi-element packs, and invalid return-type diagnostics.
- All 39 related lit tests passed on macOS arm64.
- The original reproducer successfully type-checks and emits a library
in Swift 6 mode.
Fixes #92911