| // RUN: %target-swift-frontend -enable-objc-interop -primary-file %s -emit-ir | %FileCheck %s -DINT=i%target-ptrsize --check-prefixes=CHECK,CHECK-objc |
| // RUN: %target-swift-frontend -disable-objc-interop -primary-file %s -emit-ir | %FileCheck %s -DINT=i%target-ptrsize --check-prefixes=CHECK,CHECK-native |
| sil_stage canonical |
| |
| import Builtin |
| |
| public protocol P {} |
| public class C : P {} |
| public class D<T : P> {} |
| class E {} |
| |
| public protocol Observable { |
| associatedtype Result |
| func subscribe<T: Observer>(o: T) -> () |
| } |
| |
| public protocol Observer { |
| associatedtype Result |
| } |
| |
| sil hidden @witness_method : $@convention(thin) <S where S : Observable><O where O : Observer, S.Result == O.Result> (@in S) -> @owned @callee_owned (@in O) -> () { |
| bb0(%0 : $*S): |
| %1 = witness_method $S, #Observable.subscribe : $@convention(witness_method: Observable) <τ_0_0 where τ_0_0 : Observable><τ_1_0 where τ_1_0 : Observer, τ_0_0.Result == τ_1_0.Result> (@in τ_1_0, @in_guaranteed τ_0_0) -> () |
| %2 = partial_apply %1<S, O>(%0) : $@convention(witness_method: Observable) <τ_0_0 where τ_0_0 : Observable><τ_1_0 where τ_1_0 : Observer, τ_0_0.Result == τ_1_0.Result> (@in τ_1_0, @in_guaranteed τ_0_0) -> () |
| return %2 : $@callee_owned (@in O) -> () |
| } |
| |
| // CHECK-LABEL: define internal swiftcc %T23partial_apply_forwarder1DCyAA1CCG* @"$s23unspecialized_uncurriedTA"(%swift.refcounted* |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder1CCMa"([[INT]] 0) |
| // CHECK: [[TYPE:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: [[CAST:%.*]] = bitcast %swift.refcounted* %0 to %T23partial_apply_forwarder1EC* |
| // CHECK: [[CALL:%.*]] = call swiftcc %T23partial_apply_forwarder1DC* @unspecialized_uncurried(%swift.type* [[TYPE]], i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$s23partial_apply_forwarder1CCAA1PAAWP", i32 0, i32 0), %T23partial_apply_forwarder1EC* swiftself [[CAST]]) |
| |
| sil hidden @specialized_curried : $@convention(thin) (@owned E) -> @owned @callee_owned () -> @owned D<C> { |
| bb0(%0 : $E): |
| %1 = function_ref @unspecialized_uncurried : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed E) -> @owned D<τ_0_0> |
| %2 = partial_apply %1<C>(%0) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed E) -> @owned D<τ_0_0> |
| return %2 : $@callee_owned () -> @owned D<C> |
| } |
| |
| sil hidden_external @unspecialized_uncurried : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed E) -> @owned D<τ_0_0> |
| |
| |
| // CHECK-LABEL: define internal swiftcc void @"$s7takingPTA"(%swift.refcounted* |
| // CHECK: [[CONTEXT:%.*]] = alloca %swift.refcounted* |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder1CCMa"([[INT]] 0) |
| // CHECK: [[TYPE:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: store %swift.refcounted* %0, %swift.refcounted** [[CONTEXT]] |
| // CHECK: [[CAST:%.*]] = bitcast %swift.refcounted** [[CONTEXT]] to %swift.opaque* |
| // CHECK: call swiftcc void @takingP(%swift.type* [[TYPE]], i8**{{.*}}$s23partial_apply_forwarder1CCAA1PAAWP{{.*}}, %swift.opaque* {{.*}} swiftself [[CAST]] |
| // CHECK: ret |
| sil hidden_external @takingP : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () |
| |
| sil hidden @reabstract_context : $@convention(thin) (@owned C) -> () { |
| bb0(%0 : $C): |
| %6 = alloc_stack $C |
| store %0 to %6 : $*C |
| %8 = function_ref @takingP : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () |
| %9 = partial_apply %8<C>(%6) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () |
| dealloc_stack %6 : $*C |
| strong_release %9 : $@callee_owned() -> () |
| %10 = tuple () |
| return %10 : $() |
| } |
| |
| public protocol Q { |
| associatedtype Update |
| } |
| |
| public struct BaseProducer<T> : Q { |
| public typealias Update = T |
| } |
| |
| public class WeakBox<T> {} |
| |
| public struct EmptyType {} |
| |
| sil hidden_external @takingQ : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () |
| sil hidden_external @takingQAndEmpty : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> () |
| sil hidden_external @takingEmptyAndQ : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> () |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @bind_polymorphic_param_from_context(%swift.opaque* noalias nocapture %0, %swift.type* %"\CF\84_0_1") |
| // CHECK: entry: |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder12BaseProducerVMa"([[INT]] 255, %swift.type* %"\CF\84_0_1") |
| // CHECK: [[BPTYPE:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder7WeakBoxCMa"([[INT]] 0, %swift.type* [[BPTYPE]]) |
| // CHECK: [[WEAKBOXTYPE:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: [[OBJ:%.*]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* [[WEAKBOXTYPE]] |
| // CHECK: [[WB:%.*]] = bitcast %swift.refcounted* [[OBJ]] to %T23partial_apply_forwarder7WeakBoxC* |
| // CHECK: [[REF:%.*]] = bitcast %T23partial_apply_forwarder7WeakBoxC* [[WB]] to %swift.refcounted* |
| // CHECK: [[CLOSURE:%.*]] = insertvalue { i8*, %swift.refcounted* } { i8* bitcast ({{.*}}* @"$s7takingQTA{{(\.ptrauth)?}}" to i8*), %swift.refcounted* undef }, %swift.refcounted* [[REF]], 1 |
| // CHECK: ret { i8*, %swift.refcounted* } [[CLOSURE]] |
| |
| // CHECK-LABEL: define internal swiftcc void @"$s7takingQTA"(%swift.refcounted* swiftself %0) |
| // CHECK: entry: |
| // CHECK: [[WB:%.*]] = bitcast %swift.refcounted* %0 to %T23partial_apply_forwarder7WeakBoxC* |
| // CHECK: [[TYADDR:%.*]] = getelementptr inbounds %T23partial_apply_forwarder7WeakBoxC, %T23partial_apply_forwarder7WeakBoxC* %1, i32 0, i32 0, i32 0 |
| // CHECK: [[TY:%.*]] = load %swift.type*, %swift.type** [[TYADDR]] |
| // CHECK: [[GENPARAMSADDR:%.*]] = bitcast %swift.type* [[TY]] to %swift.type** |
| // CHECK-objc: [[PARAMTYADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[GENPARAMSADDR]], {{(i64 10|i32 13)}} |
| // CHECK-native: [[PARAMTYADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[GENPARAMSADDR]], {{(i64 7|i32 10)}} |
| // CHECK: %"BaseProducer<\CF\84_0_1>" = load %swift.type*, %swift.type** [[PARAMTYADDR]] |
| // CHECK: [[WITNESS:%.*]] = call i8** @swift_getWitnessTable( |
| // CHECK: [[OBJ:%.*]] = bitcast %swift.refcounted* %0 to %T23partial_apply_forwarder7WeakBoxC.1* |
| // CHECK: tail call swiftcc void @takingQ(%T23partial_apply_forwarder7WeakBoxC.1* [[OBJ]], i8** [[WITNESS]]) |
| // CHECK: } |
| |
| sil public @bind_polymorphic_param_from_context : $@convention(thin) <τ_0_1>(@in τ_0_1) -> @owned @callee_owned () -> () { |
| bb0(%0 : $*τ_0_1): |
| %1 = alloc_ref $WeakBox<BaseProducer<τ_0_1>> |
| %8 = function_ref @takingQ : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () |
| %9 = partial_apply %8<BaseProducer<τ_0_1>>(%1) : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () |
| return %9 : $@callee_owned () -> () |
| } |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @bind_polymorphic_param_from_context_2(%swift.opaque* noalias nocapture %0, %swift.type* %"\CF\84_0_1") |
| // CHECK: [[OBJ:%.*]] = call {{.*}} @swift_allocObject |
| // CHECK: [[WB:%.*]] = bitcast %swift.refcounted* [[OBJ]] |
| // CHECK: [[REF:%.*]] = bitcast {{.*}}* [[WB]] to %swift.refcounted* |
| // CHECK: [[CLOSURE:%.*]] = insertvalue { i8*, %swift.refcounted* } { i8* bitcast ({{.*}}* @"$s15takingQAndEmptyTA{{(\.ptrauth)?}}" to i8*), %swift.refcounted* undef }, %swift.refcounted* [[REF]], 1 |
| // CHECK: } |
| sil public @bind_polymorphic_param_from_context_2 : $@convention(thin) <τ_0_1>(@in τ_0_1, EmptyType) -> @owned @callee_owned () -> () { |
| bb0(%0 : $*τ_0_1, %2: $EmptyType): |
| %1 = alloc_ref $WeakBox<BaseProducer<τ_0_1>> |
| %8 = function_ref @takingQAndEmpty : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> () |
| %9 = partial_apply %8<BaseProducer<τ_0_1>>(%1, %2) : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> () |
| return %9 : $@callee_owned () -> () |
| } |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @bind_polymorphic_param_from_context_3(%swift.opaque* noalias nocapture %0, %swift.type* %"\CF\84_0_1") |
| // CHECK: [[OBJ:%.*]] = call {{.*}} @swift_allocObject |
| // CHECK: [[WB:%.*]] = bitcast %swift.refcounted* [[OBJ]] |
| // CHECK: [[REF:%.*]] = bitcast {{.*}}* [[WB]] to %swift.refcounted* |
| // CHECK: [[CLOSURE:%.*]] = insertvalue { i8*, %swift.refcounted* } { i8* bitcast ({{.*}}* @"$s15takingEmptyAndQTA{{(\.ptrauth)?}}" to i8*), %swift.refcounted* undef }, %swift.refcounted* [[REF]], 1 |
| // CHECK: } |
| |
| sil public @bind_polymorphic_param_from_context_3 : $@convention(thin) <τ_0_1>(@in τ_0_1, EmptyType) -> @owned @callee_owned () -> () { |
| bb0(%0 : $*τ_0_1, %2: $EmptyType): |
| %1 = alloc_ref $WeakBox<BaseProducer<τ_0_1>> |
| %8 = function_ref @takingEmptyAndQ : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> () |
| %9 = partial_apply %8<BaseProducer<τ_0_1>>(%2, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> () |
| return %9 : $@callee_owned () -> () |
| } |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @bind_polymorphic_param_from_forwarder_parameter(%swift.opaque* noalias nocapture %0, %swift.type* %"\CF\84_0_1") |
| // CHECK: entry: |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder12BaseProducerVMa"([[INT]] 255, %swift.type* %"\CF\84_0_1") |
| // CHECK: [[BPTY:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder7WeakBoxCMa"([[INT]] 0, %swift.type* [[BPTY]] |
| // CHECK: [[WBTY:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: call noalias %swift.refcounted* @swift_allocObject(%swift.type* [[WBTY]] |
| // CHECK: ret void |
| |
| // CHECK-LABEL: define internal swiftcc void @"$s7takingQTA.1"(%T23partial_apply_forwarder7WeakBoxC* %0, %swift.refcounted* swiftself %1) |
| // CHECK: entry: |
| // CHECK: [[TYADDR:%.*]] = getelementptr inbounds %T23partial_apply_forwarder7WeakBoxC, %T23partial_apply_forwarder7WeakBoxC* %0 |
| // CHECK: [[TY:%.*]] = load %swift.type*, %swift.type** [[TYADDR]] |
| // CHECK: [[CAST:%.*]] = bitcast %T23partial_apply_forwarder7WeakBoxC* %0 to %T23partial_apply_forwarder7WeakBoxC.1* |
| // CHECK: [[TYPARAMSADDR:%.*]] = bitcast %swift.type* [[TY]] to %swift.type** |
| // CHECK-objc: [[TYPARAM:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[TYPARAMSADDR]], {{(i64 10|i32 13)}} |
| // CHECK-native: [[TYPARAM:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[TYPARAMSADDR]], {{(i64 7|i32 10)}} |
| // CHECK: %"BaseProducer<\CF\84_0_1>" = load %swift.type*, %swift.type** [[TYPARAM]] |
| // CHECK: [[WITNESS:%.*]] = call i8** @swift_getWitnessTable |
| // CHECK: tail call swiftcc void @takingQ(%T23partial_apply_forwarder7WeakBoxC.1* [[CAST]], i8** [[WITNESS]]) |
| // CHECK: ret void |
| |
| sil public @bind_polymorphic_param_from_forwarder_parameter : $@convention(thin) <τ_0_1>(@in τ_0_1) -> () { |
| bb0(%0 : $*τ_0_1): |
| %1 = alloc_ref $WeakBox<BaseProducer<τ_0_1>> |
| %8 = function_ref @takingQ : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () |
| %9 = partial_apply %8<BaseProducer<τ_0_1>>() : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () |
| %10 = tuple () |
| return %10 : $() |
| } |
| |
| struct S { |
| var x : Builtin.Int64 |
| } |
| |
| sil hidden_external @takingQAndS : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (S, @owned WeakBox<τ_0_0>) -> () |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc {{.*}} @bind_polymorphic_param_from_context_with_layout(%swift.opaque* noalias nocapture %0, i64 %1, %swift.type* %"\CF\84_0_1") |
| // CHECK: entry: |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder12BaseProducerVMa"([[INT]] 255, %swift.type* %"\CF\84_0_1") |
| // CHECK: [[BPTY:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s23partial_apply_forwarder7WeakBoxCMa"([[INT]] 0, %swift.type* [[BPTY]] |
| // CHECK: [[WBTY:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0 |
| // CHECK: [[WBREF:%.*]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* [[WBTY]] |
| // CHECK: [[WB:%.*]] = bitcast %swift.refcounted* [[WBREF]] to %T23partial_apply_forwarder7WeakBoxC* |
| // CHECK: [[CONTEXT0:%.*]] = call noalias %swift.refcounted* @swift_allocObject |
| // CHECK: [[CONTEXT:%.*]] = bitcast %swift.refcounted* [[CONTEXT0]] to <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>* |
| // CHECK: [[SADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>, <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>* [[CONTEXT]], i32 0, i32 {{(1|2)}} |
| // CHECK: [[XADDR:%.*]] = getelementptr inbounds %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder1SV* [[SADDR]], i32 0, i32 0 |
| // CHECK: store i64 %1, i64* [[XADDR]] |
| // CHECK: [[WBADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>, <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>* [[CONTEXT]], i32 0, i32 {{(2|3)}} |
| // CHECK: store %T23partial_apply_forwarder7WeakBoxC* [[WB]], %T23partial_apply_forwarder7WeakBoxC** [[WBADDR]] |
| // CHECK: [[CLOSURE:%.*]] = insertvalue { i8*, %swift.refcounted* } { i8* bitcast ({{.*}}* @"$s11takingQAndSTA{{(\.ptrauth)?}}" to i8*), %swift.refcounted* undef }, %swift.refcounted* [[CONTEXT0]], 1 |
| // CHECK: ret { i8*, %swift.refcounted* } [[CLOSURE]] |
| |
| // CHECK-LABEL: define internal swiftcc void @"$s11takingQAndSTA"(%swift.refcounted* swiftself %0) |
| // CHECK: entry: |
| // CHECK: [[CONTEXT:%.*]] = bitcast %swift.refcounted* %0 to <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>* |
| // CHECK: [[SADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>, <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>* [[CONTEXT]], i32 0, i32 {{(1|2)}} |
| // CHECK: [[XADDR:%.*]] = getelementptr inbounds %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder1SV* [[SADDR]], i32 0, i32 0 |
| // CHECK: [[X:%.*]] = load i64, i64* [[XADDR]] |
| // CHECK: [[WBADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>, <{ %swift.refcounted,{{.*}} %T23partial_apply_forwarder1SV, %T23partial_apply_forwarder7WeakBoxC* }>* [[CONTEXT]], i32 0, i32 {{(2|3)}} |
| // CHECK: [[WB:%.*]] = load %T23partial_apply_forwarder7WeakBoxC*, %T23partial_apply_forwarder7WeakBoxC** [[WBADDR]] |
| // CHECK: [[WBREF:%.*]] = bitcast %T23partial_apply_forwarder7WeakBoxC* [[WB]] to %swift.refcounted* |
| // CHECK: call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[WBREF]]) |
| // CHECK: [[TYADDR:%.*]] = getelementptr inbounds %T23partial_apply_forwarder7WeakBoxC, %T23partial_apply_forwarder7WeakBoxC* [[WB]], i32 0, i32 0, i32 0 |
| // CHECK: [[TY:%.*]] = load %swift.type*, %swift.type** [[TYADDR]] |
| // CHECK: %.asUnsubstituted = bitcast %T23partial_apply_forwarder7WeakBoxC* [[WB]] to %T23partial_apply_forwarder7WeakBoxC.1* |
| // CHECK: call void @swift_release(%swift.refcounted* %0) |
| // CHECK: [[GENPARAMSADDR:%.*]] = bitcast %swift.type* [[TY]] to %swift.type** |
| // CHECK-objc: [[GENPARAMADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[GENPARAMSADDR]], {{(i64 10|i32 13)}} |
| // CHECK-native: [[GENPARAMADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[GENPARAMSADDR]], {{(i64 7|i32 10)}} |
| // CHECK: %"BaseProducer<\CF\84_0_1>" = load %swift.type*, %swift.type** [[GENPARAMADDR]] |
| // CHECK: [[WITNESS:%.*]] = call i8** @swift_getWitnessTable |
| // CHECK: tail call swiftcc void @takingQAndS(i64 [[X]], %T23partial_apply_forwarder7WeakBoxC.1* %.asUnsubstituted, i8** [[WITNESS]]) |
| sil public @bind_polymorphic_param_from_context_with_layout : $@convention(thin) <τ_0_1>(@in τ_0_1, S) -> @owned @callee_owned () -> () { |
| bb0(%0 : $*τ_0_1, %1: $S): |
| %2 = alloc_ref $WeakBox<BaseProducer<τ_0_1>> |
| %8 = function_ref @takingQAndS : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (S, @owned WeakBox<τ_0_0>) -> () |
| %9 = partial_apply %8<BaseProducer<τ_0_1>>(%1, %2) : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (S, @owned WeakBox<τ_0_0>) -> () |
| return %9 : $@callee_owned () -> () |
| } |
| |
| public class Empty<T> {} |
| |
| sil private @inner_closure : $@convention(thin) <T> (Empty<T>) -> @owned Empty<T> { |
| bb0(%0 : $Empty<T>): |
| return %0 : $Empty<T> |
| } |
| |
| sil hidden @returns_closure : $@convention(thin) <T> (Empty<T>) -> (@owned Empty<T>, @callee_guaranteed @owned (Empty<T>) -> @owned Empty<T>) { |
| bb0(%0 : $Empty<T>): |
| %1 = function_ref @inner_closure : $@convention(thin) <τ_0_0> (Empty<τ_0_0>) -> @owned Empty<τ_0_0> |
| %2 = partial_apply [callee_guaranteed] %1<T>() : $@convention(thin) <τ_0_0> (Empty<τ_0_0>) -> @owned Empty<τ_0_0> |
| %5 = tuple (%0 : $Empty<T>, %2 : $@callee_guaranteed (Empty<T>) -> @owned Empty<T>) |
| return %5 : $(Empty<T>, @callee_guaranteed (Empty<T>) -> @owned Empty<T>) |
| } |
| |
| sil hidden @specializes_closure_returning_closure : $@convention(thin) () -> @callee_guaranteed (Empty<S>) -> (@owned Empty<S>, @owned @callee_guaranteed (Empty<S>) -> @owned Empty<S>) { |
| bb0: |
| %0 = function_ref @returns_closure : $@convention(thin) <τ_0_0> (Empty<τ_0_0>) -> (@owned Empty<τ_0_0>, @owned @callee_guaranteed (Empty<τ_0_0>) -> @owned Empty<τ_0_0>) |
| %1 = partial_apply [callee_guaranteed] %0<S>() : $@convention(thin) <τ_0_0> (Empty<τ_0_0>) -> (@owned Empty<τ_0_0>, @owned @callee_guaranteed (Empty<τ_0_0>) -> @owned Empty<τ_0_0>) |
| return %1 : $@callee_guaranteed (Empty<S>) -> (@owned Empty<S>, @owned @callee_guaranteed (Empty<S>) -> @owned Empty<S>) |
| } |
| |
| // CHECK-LABEL: define hidden swiftcc { i8*, %swift.refcounted* } @specializes_closure_returning_closure() #0 { |
| // CHECK: entry: |
| // CHECK: ret { i8*, %swift.refcounted* } { i8* bitcast ({{.*}} @"{{.*}}returns_closure{{.*}}" to i8*), %swift.refcounted* null } |
| |
| protocol MyEquatable { |
| static func isEqual (lhs: Self, rhs: Self) -> Builtin.Int1 |
| } |
| |
| protocol MyExtended : MyEquatable { |
| func extended() |
| } |
| public struct Inner<Element> { |
| public init() |
| public init(_ e: Element) |
| } |
| |
| extension Inner : MyEquatable where Element : MyEquatable { |
| public static func isEqual (lhs: Inner<Element>, rhs: Inner<Element>) -> Builtin.Int1 |
| } |
| |
| public struct Outer<Value> { |
| init() |
| } |
| |
| extension Outer : MyEquatable where Value : MyEquatable { |
| public static func isEqual (lhs: Outer<Value>, rhs: Outer<Value>) -> Builtin.Int1 |
| } |
| |
| public struct Outermost<Value> { |
| } |
| |
| sil @$closure : $@convention(method) <Value where Value : MyEquatable> (Outer<Value>, Outer<Value>, @thin Outer<Value>.Type) -> Builtin.Int1 |
| sil @$closure2 : $@convention(method) <Value where Value : MyEquatable> (Outermost<Value>, Outermost<Value>, @thin Outermost<Value>.Type) -> Builtin.Int1 |
| |
| sil @$dont_crash_test_capture_specialized_conditional_conformance : $@convention(thin) <Element where Element : MyExtended> (Outer<Inner<Element>>) -> () { |
| bb0(%0 : $Outer<Inner<Element>>): |
| %2 = alloc_stack $Outer<Inner<Element>> |
| store %0 to %2 : $*Outer<Inner<Element>> |
| %4 = metatype $@thin Outer<Inner<Element>>.Type |
| %5 = function_ref @$closure : $@convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 |
| %6 = partial_apply [callee_guaranteed] %5<Inner<Element>>(%4) : $@convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 |
| strong_release %6 : $@callee_guaranteed (Outer<Inner<Element>>, Outer<Inner<Element>>) -> Builtin.Int1 |
| dealloc_stack %2 : $*Outer<Inner<Element>> |
| %15 = tuple () |
| return %15 : $() |
| } |
| |
| protocol AssocType { |
| associatedtype A : MyExtended |
| } |
| |
| sil @$dont_crash_test_capture_specialized_conditional_conformance_associated_type : $@convention(thin) <Element where Element : AssocType> (Outer<Inner<Element.A>>) -> () { |
| bb0(%0 : $Outer<Inner<Element.A>>): |
| %2 = alloc_stack $Outer<Inner<Element.A>> |
| store %0 to %2 : $*Outer<Inner<Element.A>> |
| %4 = metatype $@thin Outer<Inner<Element.A>>.Type |
| %5 = function_ref @$closure : $@convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 |
| %6 = partial_apply [callee_guaranteed] %5<Inner<Element.A>>(%4) : $@convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 |
| strong_release %6 : $@callee_guaranteed (Outer<Inner<Element.A>>, Outer<Inner<Element.A>>) -> Builtin.Int1 |
| dealloc_stack %2 : $*Outer<Inner<Element.A>> |
| %15 = tuple () |
| return %15 : $() |
| } |
| |
| sil @$dont_crash_test_capture_specialized_conditional_conformance_nested : $@convention(thin) <A, B, Element where Element : MyEquatable> (Outer<Inner<Element>>) -> () { |
| bb0(%0 : $Outer<Inner<Element>>): |
| %4 = metatype $@thin Outermost<Outer<Inner<Element>>>.Type |
| %5 = function_ref @$closure2 : $@convention(method) <Value where Value : MyEquatable> (Outermost<Value>, Outermost<Value>, @thin Outermost<Value>.Type) -> Builtin.Int1 |
| %6 = partial_apply [callee_guaranteed] %5<Outer<Inner<Element>>>(%4) : $@convention(method) <Value where Value : MyEquatable> (Outermost<Value>, Outermost<Value>, @thin Outermost<Value>.Type) -> Builtin.Int1 |
| strong_release %6 : $@callee_guaranteed (Outermost<Outer<Inner<Element>>>, Outermost<Outer<Inner<Element>>>) -> Builtin.Int1 |
| %15 = tuple () |
| return %15 : $() |
| } |
| |
| |
| sil_vtable WeakBox {} |
| sil_vtable C {} |
| sil_vtable D {} |
| sil_vtable E {} |
| sil_vtable Empty {} |
| sil_witness_table C: P module main {} |