blob: 04c77251b139477d3b212dedb65543418aa2e0c1 [file] [log] [blame]
// 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()
}
}
}
}