Files
swift-mirror/test/IRGen/variadic_generic_fulfillment_tuple.swift
Slava Pestov f17baefd7a IRGen: Fix miscompile when a generic parameter is fixed to a tuple containing a pack
If you had something like:

    struct G<T> {
      func f<each U>(_: repeat each U) where T == (repeat each U) {}
    }

We would fulfill 'each U' from the metadata for 'G<(repeat each U)>',
by taking apart the tuple metadata for `(repeat each U)` and forming
a pack.

However this code path was only intended to kick in for a tuple
conformance witness thunk. In the general case, this optimization
is not correct, because if 'each U' is substituted with a
one-element pack, the generic argument of `G<(repeat each U)>` is
just that one element's metadata, and not a tuple. In fact, we
cannot distinguish the one-element tuple case, because the wrapped
element may itself be a tuple.

The fix is to just split off FulfillmentMap::searchTupleTypeMetadata()
from searchTypeMetadata(), and only call the former when we're in
the specific situation that requires it.

- Fixes https://github.com/swiftlang/swift/issues/78191.
- Fixes rdar://problem/135325886.
2025-05-16 17:34:11 -04:00

14 lines
631 B
Swift

// RUN: %target-swift-frontend -emit-ir %s -target %target-swift-5.9-abi-triple | %FileCheck %s
struct G<T> {
var t: T
// Make sure we *don't* try to fulfill the pack from the tuple, because we cannot
// distinguish the one-element case that way.
// CHECK-LABEL: define {{.*}} void @"$s34variadic_generic_fulfillment_tuple1GV20fixOuterGenericParamyACyqd__qd__Qp_tGqd__qd__Qp_t_tRvd__qd__qd__Qp_tRszlF"(ptr noalias sret(%swift.opaque) %0, ptr noalias %1, {{i32|i64}} %2, ptr %"each U", ptr noalias swiftself %3)
func fixOuterGenericParam<each U>(_ t: T) -> G<T> where T == (repeat each U) {
return G<T>(t: t)
}
}