blob: ebdfab0c3fb7b5792efcacbacad5db4dd0ba447b [file] [log] [blame]
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -assume-parsing-unqualified-ownership-sil %s | %FileCheck %s -DINT=i%target-ptrsize
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -O -assume-parsing-unqualified-ownership-sil %s
sil_stage canonical
import Builtin
import Swift
import SwiftShims
import resilient_protocol
// Generic witness table pattern for ConformingType : ResilientProtocol
// CHECK: @"$s19protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWG"
// CHECK-SAME: internal constant %swift.generic_witness_table_cache {
// -- number of witness table entries
// CHECK-SAME: i16 1,
// -- size of private area
// CHECK-SAME: i16 0,
// -- the protocol descriptor
// CHECK-SAME: @"{{got.|__imp_}}$s18resilient_protocol22OtherResilientProtocolMp"
// -- the template
// CHECK-SAME: @"$s19protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWp"
// -- resilient witnesses
// CHECK-SAME: i32 0,
// -- instantiator function
// CHECK-SAME: i32 0
// CHECK-SAME: }
// Protocol descriptor for ResilientProtocol
// CHECK: [[RESILIENT_PROTOCOL_NAME:@.*]] = private constant [18 x i8] c"ResilientProtocol\00
// CHECK: [[ASSOCIATED_TYPES_T:@.*]] = private constant [2 x i8] c"T\00"
// CHECK: @"$s19protocol_resilience17ResilientProtocolMp" = {{(dllexport )?}}{{(protected )?}}constant
// CHECK-SAME: i32 196675,
// CHECK-SAME: @"$s19protocol_resilienceMXM"
// CHECK-SAME: [[RESILIENT_PROTOCOL_NAME]]
// CHECK-SAME: i32 1,
// CHECK-SAME: i32 8,
// CHECK-SAME: [[ASSOCIATED_TYPES_T]]
// Requirement signature
// CHECK-SAME: i32 128,
// CHECK-SAME: @"$sx1T_MXA"
// CHECK-SAME: @"$s19protocol_resilience17ResilientProtocolMp"
// Protocol requirements
// CHECK-SAME: %swift.protocol_requirement { i32 8, i32 0 },
// CHECK-SAME: %swift.protocol_requirement { i32 7, i32 0 },
// CHECK-SAME: %swift.protocol_requirement { i32 17, i32 0 },
// CHECK-SAME: %swift.protocol_requirement { i32 17, i32 0 },
// CHECK-SAME: %swift.protocol_requirement { i32 17,
// CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.opaque*, %swift.type*, i8**)* @defaultC to [[INT]]),
// CHECK-SAME: },
// CHECK-SAME: %swift.protocol_requirement { i32 17,
// CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.opaque*, %swift.type*, i8**)* @defaultD to [[INT]]),
// CHECK-SAME: },
// CHECK-SAME: %swift.protocol_requirement { i32 1,
// CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.type*, %swift.type*, i8**)* @defaultE to [[INT]]),
// CHECK-SAME: },
// CHECK-SAME: %swift.protocol_requirement { i32 1,
// CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.type*, %swift.type*, i8**)* @defaultF to [[INT]]),
// CHECK-SAME: }
// CHECK-SAME: }
public protocol ResilientProtocol {
associatedtype T : OtherResilientProtocol
func noDefaultA()
func noDefaultB()
func defaultC()
func defaultD()
static func defaultE()
static func defaultF()
}
// Protocol is not public -- doesn't need default witness table
// CHECK: @"$s19protocol_resilience16InternalProtocolMp" = hidden constant
// CHECK-SAME: i32 65603,
// CHECK-SAME: @"$s19protocol_resilienceMXM"
// CHECK-SAME: i32 0,
// CHECK-SAME: i32 1,
// CHECK-SAME: i32 0,
// CHECK-SAME: }
protocol InternalProtocol {
func f()
}
// Generic witness table pattern for ConformsWithRequirements : ProtocolWithRequirements
// CHECK: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp"
// CHECK-SAME: internal constant [1 x i8*] [
// -- conformance descriptor
// CHECK-SAME: "$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAMc"
// CHECK-SAME: ]
// CHECK: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWG"
// -- number of witness table entries
// CHECK-SAME: i16 1,
// -- size of private area
// CHECK-SAME: i16 0,
// -- the protocol descriptor
// CHECK-SAME: @"{{got.|__imp_}}$s18resilient_protocol24ProtocolWithRequirementsMp"
// -- the template
// CHECK-SAME: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp"
// -- resilient witnesses
// CHECK-SAME: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWr"
// -- instantiator function
// CHECK-SAME: i32 0
// CHECK-SAME: }
// CHECK: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWr"
// CHECK-SAME: internal constant {
// -- type metadata for associated type
// CHECK-SAME: @"{{got.|__imp_}}$s1T18resilient_protocol24ProtocolWithRequirementsPTl"
// CHECK-SAME: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AA1TWt"
// CHECK-SAME: @"{{got.|__imp_}}$s18resilient_protocol24ProtocolWithRequirementsP5firstyyFTq"
// CHECK-SAME: @firstWitness
// CHECK-SAME: @"{{got.|__imp_}}$s18resilient_protocol24ProtocolWithRequirementsP6secondyyFTq"
// CHECK-SAME: @secondWitness
// CHECK-SAME: }
// Witness table for conformance with resilient associated type
// CHECK: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWP" = {{(protected )?}}hidden constant [3 x i8*] [
// CHECK-SAME: i8* bitcast (i8** ()* @"$s19protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWa" to i8*)
// CHECK-SAME: i8* bitcast (%swift.metadata_response ([[INT]])* @"$s19protocol_resilience23ResilientConformingTypeVMa" to i8*)
// CHECK-SAME: ]
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @defaultC(%swift.opaque* noalias nocapture swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK-NEXT: entry:
sil @defaultC : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> () {
bb0(%0 : $*Self):
// CHECK-NEXT: %[[SELF:.*]] = alloca %swift.type*
// CHECK-NEXT: store %swift.type* %Self, %swift.type** %[[SELF]]
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @defaultD(%swift.opaque* noalias nocapture swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK-NEXT: entry:
sil @defaultD : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> () {
bb0(%0 : $*Self):
// Make sure we can emit direct references to other default implementations
// CHECK-NEXT: %[[SELF:.*]] = alloca %swift.type*
// CHECK-NEXT: store %swift.type* %Self, %swift.type** %[[SELF]]
// CHECK-NEXT: call swiftcc void @defaultC(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable)
%fn1 = function_ref @defaultC : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
%ignore1 = apply %fn1<Self>(%0) : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
// Make sure we can do dynamic dispatch to other protocol requirements
// from a default implementation
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %SelfWitnessTable, i32 5
// CHECK-NEXT: [[WITNESS_FN:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[WITNESS_FN]] to void (%swift.opaque*, %swift.type*, i8**)*
// CHECK-NEXT: call swiftcc void [[WITNESS]](%swift.opaque* noalias nocapture swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable)
%fn2 = witness_method $Self, #ResilientProtocol.defaultC!1 : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
%ignore2 = apply %fn2<Self>(%0) : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
// Make sure we can partially apply a static reference to a default
// implementation
// CHECK-NEXT: [[WTABLE:%.*]] = bitcast i8** %SelfWitnessTable to i8*
// CHECK-NEXT: [[CONTEXT:%.*]] = call noalias %swift.refcounted* @swift_allocObject({{.*}})
// CHECK-NEXT: [[LAYOUT:%.*]] = bitcast %swift.refcounted* [[CONTEXT]] to <{ %swift.refcounted, [{{4|8}} x i8], i8* }>*
// CHECK: [[WTABLE_ADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [{{4|8}} x i8], i8* }>, <{ %swift.refcounted, [{{4|8}} x i8], i8* }>* [[LAYOUT]], i32 0, i32 2
// CHECK-NEXT: store i8* [[WTABLE]], i8** [[WTABLE_ADDR]]
%fn3 = function_ref @defaultC : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
%ignore3 = partial_apply %fn3<Self>() : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @defaultE(%swift.type* swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK-NEXT: entry:
sil @defaultE : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> () {
bb0(%0 : $@thick Self.Type):
// Make sure we can emit direct references to other default implementations
// CHECK-NEXT: %[[SELF:.*]] = alloca %swift.type*
// CHECK-NEXT: store %swift.type* %Self, %swift.type** %[[SELF]]
// CHECK-NEXT: call swiftcc void @defaultF(%swift.type* swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable)
%fn1 = function_ref @defaultF : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
%ignore1 = apply %fn1<Self>(%0) : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
// Make sure we can do dynamic dispatch to other protocol requirements
// from a default implementation
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %SelfWitnessTable, i32 8
// CHECK-NEXT: [[WITNESS_FN:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[WITNESS_FN]] to void (%swift.type*, %swift.type*, i8**)*
// CHECK-NEXT: call swiftcc void [[WITNESS]](%swift.type* swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable)
%fn2 = witness_method $Self, #ResilientProtocol.defaultF!1 : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
%ignore2 = apply %fn2<Self>(%0) : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
// Make sure we can partially apply a static reference to a default
// implementation
// CHECK-NEXT: [[WTABLE:%.*]] = bitcast i8** %SelfWitnessTable to i8*
// CHECK-NEXT: [[CONTEXT:%.*]] = call noalias %swift.refcounted* @swift_allocObject({{.*}})
// CHECK-NEXT: [[LAYOUT:%.*]] = bitcast %swift.refcounted* [[CONTEXT]] to <{ %swift.refcounted, [{{4|8}} x i8], i8* }>*
// CHECK: [[WTABLE_ADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [{{4|8}} x i8], i8* }>, <{ %swift.refcounted, [{{4|8}} x i8], i8* }>* [[LAYOUT]], i32 0, i32 2
// CHECK-NEXT: store i8* [[WTABLE]], i8** [[WTABLE_ADDR]]
%fn3 = function_ref @defaultF : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
%ignore3 = partial_apply %fn3<Self>() : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @defaultF(%swift.type* swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK-NEXT: entry:
sil @defaultF : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@thick Self.Type) -> () {
bb0(%0 : $@thick Self.Type):
// CHECK-NEXT: %[[SELF:.*]] = alloca %swift.type*
// CHECK-NEXT: store %swift.type* %Self, %swift.type** %[[SELF]]
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
sil_default_witness_table ResilientProtocol {
no_default
no_default
no_default
no_default
method #ResilientProtocol.defaultC!1: @defaultC
method #ResilientProtocol.defaultD!1: @defaultD
method #ResilientProtocol.defaultE!1: @defaultE
method #ResilientProtocol.defaultF!1: @defaultF
}
public struct ResilientConformingType : OtherResilientProtocol {}
sil_witness_table ResilientConformingType : OtherResilientProtocol module protocol_resilience {}
struct ConformingStruct : ResilientProtocol {
typealias T = ResilientConformingType
func noDefaultA()
func noDefaultB()
func defaultC()
func defaultD()
static func defaultE()
static func defaultF()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @noDefaultA(%T19protocol_resilience16ConformingStructV* noalias nocapture swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK-NEXT: entry:
sil @noDefaultA : $@convention(witness_method: ResilientProtocol) (@in_guaranteed ConformingStruct) -> () {
bb0(%0 : $*ConformingStruct):
// Make sure we can emit direct references to default implementations with a
// concrete Self type.
// CHECK-NEXT: [[SELF:%.*]] = bitcast %T19protocol_resilience16ConformingStructV* %0 to %swift.opaque*
// CHECK-NEXT: call swiftcc void @defaultC(%swift.opaque* noalias nocapture swiftself [[SELF]], %swift.type* bitcast ({{i32|i64}}* {{.*}}) to %swift.type*), i8** getelementptr inbounds ([9 x i8*], [9 x i8*]* @"$s19protocol_resilience16ConformingStructVAA17ResilientProtocolAAWP", i32 0, i32 0))
%fn1 = function_ref @defaultC : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
%ignore1 = apply %fn1<ConformingStruct>(%0) : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @noDefaultB(%T19protocol_resilience16ConformingStructV* noalias nocapture swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK-NEXT: entry:
sil @noDefaultB : $@convention(witness_method: ResilientProtocol) (@in_guaranteed ConformingStruct) -> () {
bb0(%0 : $*ConformingStruct):
// Make sure we can partially apply direct references to default implementations
// CHECK-NEXT: [[CONTEXT:%.*]] = call noalias %swift.refcounted* @swift_allocObject({{.*}})
// CHECK-NEXT: [[LAYOUT:%.*]] = bitcast %swift.refcounted* [[CONTEXT]] to <{ %swift.refcounted, i8* }>*
// CHECK-NEXT: [[WTABLE:%.*]] = getelementptr inbounds <{ %swift.refcounted, i8* }>, <{ %swift.refcounted, i8* }>* [[LAYOUT]], i32 0, i32 1
// CHECK-NEXT: store i8* bitcast ([9 x i8*]* @"$s19protocol_resilience16ConformingStructVAA17ResilientProtocolAAWP" to i8*), i8** [[WTABLE]]
%fn1 = function_ref @defaultC : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
%ignore1 = partial_apply %fn1<ConformingStruct>() : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
sil_witness_table ConformingStruct : ResilientProtocol module protocol_resilience {
associated_type_protocol (T: OtherResilientProtocol): ResilientConformingType: OtherResilientProtocol module protocol_resilience
associated_type T: ResilientConformingType
method #ResilientProtocol.noDefaultA!1: @noDefaultA
method #ResilientProtocol.noDefaultB!1: @noDefaultB
method #ResilientProtocol.defaultC!1: @defaultC
method #ResilientProtocol.defaultD!1: @defaultD
method #ResilientProtocol.defaultE!1: @defaultE
method #ResilientProtocol.defaultF!1: @defaultF
}
//
// Make sure resilient conformances are accessed with an accessor function
//
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doSomething(%swift.opaque* noalias nocapture, %swift.type* %T, i8** %T.OtherResilientProtocol)
sil @doSomething : $@convention(thin) <T : OtherResilientProtocol> (@in T) -> () {
bb0(%0 : $*T):
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @passConformingType(%T19protocol_resilience23ResilientConformingTypeV* noalias nocapture)
sil @passConformingType : $@convention(thin) (@in ResilientConformingType) -> () {
bb0(%0 : $*ResilientConformingType):
// CHECK-NEXT: entry:
// CHECK-NEXT: [[ARG:%.*]] = bitcast %T19protocol_resilience23ResilientConformingTypeV* %0 to %swift.opaque*
// CHECK-NEXT: [[WTABLE:%.*]] = call i8** @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWl"()
// CHECK-NEXT: call swiftcc void @doSomething(%swift.opaque* noalias nocapture [[ARG]], %swift.type* bitcast ({{i32|i64}}* getelementptr inbounds ({{.*}} @"$s19protocol_resilience23ResilientConformingTypeVMf", i32 0, i32 1) to %swift.type*), i8** [[WTABLE]])
%fn = function_ref @doSomething : $@convention(thin) <T : OtherResilientProtocol> (@in T) -> ()
%ignore = apply %fn<ResilientConformingType>(%0) : $@convention(thin) <T : OtherResilientProtocol> (@in T) -> ()
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
// Caching witness table accessor
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} linkonce_odr hidden i8** @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWl"()
// CHECK-NEXT: entry:
// CHECK-NEXT: [[CACHE:%.*]] = load i8**, i8*** @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWL"
// CHECK-NEXT: [[COND:%.*]] = icmp eq i8** [[CACHE]], null
// CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont
// CHECK: cacheIsNull:
// CHECK: [[WTABLE:%.*]] = call i8** @"$s19protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWa"()
// CHECK-NEXT: store atomic i8** [[WTABLE]], i8*** @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWL" release
// CHECK-NEXT: br label %cont
// CHECK: cont:
// CHECK-NEXT: [[RESULT:%.*]] = phi i8** [ [[CCHE:%.*]], %entry ], [ [[WTABLE:%.*]], %cacheIsNull ]
// CHECK-NEXT: ret i8** [[RESULT]]
// Resilient conformance -- must call a runtime function
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} i8** @"$s19protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWa"()
// CHECK-NEXT: entry:
// CHECK-NEXT: [[WTABLE:%.*]] = call i8** @swift_getGenericWitnessTable(%swift.generic_witness_table_cache* @"$s19protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWG", %swift.type* null, i8*** null)
// CHECK-NEXT: ret i8** [[WTABLE]]
//
// If a protocol refines a resilient protocol, any conformances are
// resilient too
//
protocol RefinesOtherResilientProtocol : OtherResilientProtocol {}
struct AnotherConformingStruct : RefinesOtherResilientProtocol {}
sil_witness_table AnotherConformingStruct : RefinesOtherResilientProtocol module protocol_resilience {
base_protocol OtherResilientProtocol: AnotherConformingStruct: OtherResilientProtocol module protocol_resilience
}
sil_witness_table hidden AnotherConformingStruct: OtherResilientProtocol module protocol_resilience {
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doSomethingRefined(%swift.opaque* noalias nocapture, %swift.type* %T, i8** %T.RefinesOtherResilientProtocol)
sil @doSomethingRefined : $@convention(thin) <T : RefinesOtherResilientProtocol> (@in T) -> () {
bb0(%0 : $*T):
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @passConformingTypeRefined(%T19protocol_resilience23AnotherConformingStructV* noalias nocapture)
sil @passConformingTypeRefined : $@convention(thin) (@in AnotherConformingStruct) -> () {
bb0(%0 : $*AnotherConformingStruct):
// CHECK-NEXT: entry:
// CHECK-NEXT: [[ARG:%.*]] = bitcast %T19protocol_resilience23AnotherConformingStructV* %0 to %swift.opaque*
// CHECK-NEXT: [[WTABLE:%.*]] = call i8** @"$s19protocol_resilience23AnotherConformingStructVAcA29RefinesOtherResilientProtocolAAWl"()
// CHECK-NEXT: call swiftcc void @doSomethingRefined(%swift.opaque* noalias nocapture [[ARG]], %swift.type* bitcast ({{i32|i64}}* getelementptr inbounds ({{.*}} @"$s19protocol_resilience23AnotherConformingStructVMf", i32 0, i32 1) to %swift.type*), i8** [[WTABLE]])
%fn = function_ref @doSomethingRefined : $@convention(thin) <T : RefinesOtherResilientProtocol> (@in T) -> ()
%ignore = apply %fn<AnotherConformingStruct>(%0) : $@convention(thin) <T : RefinesOtherResilientProtocol> (@in T) -> ()
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
//
// If an associated type conformance is resilient, the overall
// conformance is not necessarily resilient, because we access
// the associated type conformance lazily.
//
protocol HasResilientAssoc {
associatedtype T : OtherResilientProtocol
}
struct ConformsWithResilientAssoc : HasResilientAssoc {
typealias T = ResilientConformingType
}
sil_witness_table ConformsWithResilientAssoc : HasResilientAssoc module protocol_resilience {
associated_type_protocol (T: OtherResilientProtocol): ResilientConformingType: OtherResilientProtocol module protocol_resilience
associated_type T: ResilientConformingType
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doSomethingAssoc(%swift.opaque* noalias nocapture, %swift.type* %T, i8** %T.HasResilientAssoc)
sil @doSomethingAssoc : $@convention(thin) <T : HasResilientAssoc> (@in T) -> () {
bb0(%0 : $*T):
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @passConformingTypeAssoc(%T19protocol_resilience26ConformsWithResilientAssocV* noalias nocapture)
sil @passConformingTypeAssoc : $@convention(thin) (@in ConformsWithResilientAssoc) -> () {
bb0(%0 : $*ConformsWithResilientAssoc):
// CHECK-NEXT: entry:
// CHECK-NEXT: [[ARG:%.*]] = bitcast %T19protocol_resilience26ConformsWithResilientAssocV* %0 to %swift.opaque*
// CHECK-NEXT: call swiftcc void @doSomethingAssoc(%swift.opaque* noalias nocapture [[ARG]], %swift.type* bitcast ({{i32|i64}}* getelementptr inbounds ({{.*}} @"$s19protocol_resilience26ConformsWithResilientAssocVMf", i32 0, i32 1) to %swift.type*), i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWP", i32 0, i32 0))
%fn = function_ref @doSomethingAssoc : $@convention(thin) <T : HasResilientAssoc> (@in T) -> ()
%ignore = apply %fn<ConformsWithResilientAssoc>(%0) : $@convention(thin) <T : HasResilientAssoc> (@in T) -> ()
// CHECK-NEXT: ret void
%result = tuple ()
return %result : $()
}
struct ConformsWithRequirements : ProtocolWithRequirements {
typealias T = Int
func first() {}
func second() {}
}
sil @firstWitness : $@convention(witness_method: ProtocolWithRequirements) (@in_guaranteed ConformsWithRequirements) -> () {
bb0(%0 : $*ConformsWithRequirements):
unreachable
}
sil @secondWitness : $@convention(witness_method: ProtocolWithRequirements) (@in_guaranteed ConformsWithRequirements) -> () {
bb0(%0 : $*ConformsWithRequirements):
unreachable
}
sil_witness_table ConformsWithRequirements : ProtocolWithRequirements module protocol_resilience {
associated_type T: Int
method #ProtocolWithRequirements.first!1: @firstWitness
method #ProtocolWithRequirements.second!1: @secondWitness
}
//
// Witness table accessors for fragile conformances are emitted last
//
// Fragile conformance -- no runtime calls needed
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} hidden i8** @"$s19protocol_resilience16ConformingStructVAA17ResilientProtocolAAWa"()
// CHECK-NEXT: entry:
// CHECK-NEXT: ret i8** getelementptr inbounds ([9 x i8*], [9 x i8*]* @"$s19protocol_resilience16ConformingStructVAA17ResilientProtocolAAWP", i32 0, i32 0)