| // RUN: %target-swift-frontend -disable-type-layout -enable-library-evolution -disable-availability-checking -emit-ir -primary-file %s | %FileCheck %s |
| |
| public protocol E {} |
| |
| public struct Pair<T, V> : E { |
| var fst : T |
| var snd : V |
| |
| public init(_ f: T, _ s: V) { |
| self.fst = f |
| self.snd = s |
| } |
| |
| public func foobar() -> some E { |
| return self |
| } |
| } |
| |
| @inlinable |
| public func usePair<T, V>(_ t: T, _ v: V) { |
| var x = Pair(t, v) |
| let q = x.foobar() |
| let u = x.foobar() |
| let p = Pair(q, u) |
| print(p) |
| } |
| |
| protocol P { } |
| |
| struct C<S : Hashable> { |
| struct Inner {} |
| |
| init(_ s: S) { } |
| |
| func getInner() -> Inner { |
| return Inner() |
| } |
| } |
| |
| struct O<T> { |
| var t: T |
| |
| init(_ t: T) { |
| self.t = t |
| } |
| } |
| |
| struct M<T, V> : P { |
| init(_ f: T, _ s: V) { |
| } |
| |
| func foobar() -> some P { |
| return self |
| } |
| } |
| |
| public func test2<S : Hashable, T, V>(_ s: S, _ t: T, _ v: V) { |
| var x = M(C(s).getInner(), t) |
| let q = x.foobar() |
| let u = x.foobar() |
| let y = O(q) |
| print(y) |
| } |
| |
| // CHECK-LABEL: define{{.*}} swiftcc void @"$s31opaque_result_type_substitution7usePairyyx_q_tr0_lF"({{.*}}, %swift.type* %T, %swift.type* %V) |
| // CHECK: [[PAIR_TV:%.*]] = call swiftcc %swift.metadata_response @"$s31opaque_result_type_substitution4PairVMa"({{.*}}, %swift.type* %T, %swift.type* %V) |
| // CHECK: [[MD:%.*]] = extractvalue %swift.metadata_response [[PAIR_TV]], 0 |
| // CHECK: [[PAIR_OPAQUE:%.*]] = call swiftcc %swift.metadata_response @"$s31opaque_result_type_substitution4PairVMa"({{.*}}, %swift.type* [[MD]], %swift.type* [[MD]]) |
| // CHECK: [[MD2:%.*]] = extractvalue %swift.metadata_response [[PAIR_OPAQUE]], 0 |
| // CHECK: call {{.*}}* @"$s31opaque_result_type_substitution4PairVyAC6foobarQryFQOyxq__Qo_AEGr0_lWOh"({{.*}}, %swift.type* {{.*}}, %swift.type* [[MD2]]) |
| |
| public protocol Thing { } |
| |
| public struct Thingy : Thing {} |
| |
| public protocol KeyProto { |
| associatedtype Value |
| } |
| |
| extension KeyProto { |
| public static func transform3<T : Thing>( |
| _ transform: @escaping (A<Self>) -> T) |
| -> some Thing { |
| return Thingy() |
| } |
| } |
| |
| public struct A<Key : KeyProto> {} |
| |
| extension A { |
| public func transform2<T>(_ transform: @escaping (Key.Value) -> T) -> Thingy { |
| return Thingy() |
| } |
| } |
| |
| struct AKey : KeyProto { |
| typealias Value = Int |
| } |
| |
| extension Thing { |
| public func transform<K>(key _: K.Type = K.self, transform: @escaping (inout K) -> Void) -> some Thing { |
| return Thingy() |
| } |
| } |
| |
| struct OutterThing<Content : Thing> : Thing { |
| let content: Content |
| |
| init(_ c: Content) { |
| self.content = c |
| } |
| |
| var body: some Thing { |
| return AKey.transform3 { y in |
| y.transform2 { i in |
| self.content.transform( |
| key: Thingy.self) { value in } |
| } |
| } |
| } |
| } |
| |
| public protocol W {} |
| |
| struct Key : W {} |
| |
| extension W { |
| public static func transform(_ transform: @escaping (P1<Self>) -> ()) -> some W { |
| return Key() |
| } |
| } |
| |
| public struct P1<Key : W> { } |
| |
| extension P1 { |
| public func transform2<T>(_ transform: @escaping (Key) -> T) { } |
| } |
| |
| public struct T<Content> : W { |
| public init(content : ()->Content) {} |
| } |
| |
| public struct Content<Content> : W { |
| public init(content: Content) {} |
| } |
| |
| extension W { |
| func moo() -> some W { |
| return Content(content: self) |
| } |
| } |
| |
| struct Test<Label : W> { |
| var label: Label |
| // This function used to crash. |
| var dontCrash: some W { |
| return Key.transform { y in |
| y.transform2 { i in |
| T() { |
| return self.label |
| }.moo() |
| } |
| } |
| } |
| } |