mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
465 lines
20 KiB
Plaintext
465 lines
20 KiB
Plaintext
// RUN: %empty-directory(%t)
|
|
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
|
|
// RUN: %target-swift-frontend -I %t -emit-ir -Xllvm -sil-disable-pass=Simplification -enable-library-evolution %s | %FileCheck %s -DINT=i%target-ptrsize
|
|
// RUN: %target-swift-frontend -I %t -emit-ir -Xllvm -sil-disable-pass=Simplification -enable-library-evolution -O %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
import resilient_protocol
|
|
|
|
// Protocol conformance descriptor for ResilientConformingType : OtherResilientProtocol
|
|
|
|
// CHECK: @"$s19protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAMc" =
|
|
|
|
// CHECK-SAME: i32 131072,
|
|
|
|
// -- number of witness table entries
|
|
// CHECK-SAME: i16 0,
|
|
|
|
// -- size of private area + 'requires instantiation' bit
|
|
// CHECK-SAME: i16 1,
|
|
|
|
// -- 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: @"symbolic 1T_____Qz 19protocol_resilience17ResilientProtocolP"
|
|
// CHECK-SAME: @"$s19protocol_resilience17ResilientProtocolMp"
|
|
|
|
// Protocol requirements
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(1797193736)|(8)}}, i32 0 },
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(-1947336697)|(7)}}, i32 0 },
|
|
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(-48627695)|(17)}}, i32 0 },
|
|
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(-1745420271)|(17)}}, i32 0 },
|
|
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(-544407535)|(17)}},
|
|
// CHECK-SAME: {{(i32( | trunc \(i64 )sub \()?}}[[INT]] ptrtoint (ptr @defaultC to [[INT]])
|
|
// CHECK-SAME: },
|
|
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(1717370897)|(17)}},
|
|
// CHECK-SAME: {{(i32( | trunc \(i64 )sub \()?}}[[INT]] ptrtoint (ptr @defaultD to [[INT]])
|
|
// CHECK-SAME: },
|
|
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(297926657)|(1)}},
|
|
// CHECK-SAME: {{(i32( | trunc \(i64 )sub \()?}}[[INT]] ptrtoint (ptr @defaultE to [[INT]])
|
|
// CHECK-SAME: },
|
|
|
|
// CHECK-SAME: %swift.protocol_requirement { i32 {{(351797249)|(1)}},
|
|
// CHECK-SAME: {{(i32( | trunc \(i64 )sub \()?}}[[INT]] ptrtoint (ptr @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()
|
|
}
|
|
|
|
// No generic witness table pattern for ConformsWithRequirements : ProtocolWithRequirements; it's all resilient
|
|
|
|
// CHECK-NOT: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp" =
|
|
|
|
|
|
// No witness table pattern for conformance with resilient associated type
|
|
|
|
// CHECK-NOT: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWp" = {{(protected )?}}internal
|
|
|
|
|
|
// ConformsWithRequirements protocol conformance descriptor
|
|
|
|
// CHECK: "$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAMc" = hidden constant {
|
|
|
|
// -- flags
|
|
// CHECK-SAME: i32 196608,
|
|
|
|
// CHECK-SAME: i32 3,
|
|
|
|
// -- type metadata for associated type
|
|
// CHECK-SAME: @"{{got.|\\01__imp__?}}$s1T18resilient_protocol24ProtocolWithRequirementsPTl"
|
|
// CHECK-SAME: @"symbolic Si"
|
|
|
|
// CHECK-SAME: @"{{got.|\\01__imp__?}}$s18resilient_protocol24ProtocolWithRequirementsP5firstyyFTq"
|
|
// CHECK-SAME: @firstWitness
|
|
|
|
// CHECK-SAME: @"{{got.|\\01__imp__?}}$s18resilient_protocol24ProtocolWithRequirementsP6secondyyFTq"
|
|
// CHECK-SAME: @secondWitness
|
|
|
|
// -- number of witness table entries
|
|
// CHECK-SAME: i16 0,
|
|
|
|
// -- size of private area + 'requires instantiation' bit
|
|
// CHECK-SAME: i16 1,
|
|
|
|
// -- instantiator function
|
|
// CHECK-SAME: i32 0
|
|
|
|
// CHECK-SAME: }
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @defaultC(ptr noalias swiftself %0, ptr %Self, ptr %SelfWitnessTable)
|
|
// CHECK-NEXT: entry:
|
|
sil @defaultC : $@convention(witness_method: ResilientProtocol) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> () {
|
|
bb0(%0 : $*Self):
|
|
// CHECK-NEXT: %[[SELF:.*]] = alloca ptr
|
|
// CHECK-NEXT: store ptr %Self, ptr %[[SELF]]
|
|
// CHECK-NEXT: ret void
|
|
%result = tuple ()
|
|
return %result : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @defaultD(ptr noalias swiftself %0, ptr %Self, ptr %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 ptr
|
|
// CHECK-NEXT: store ptr %Self, ptr %[[SELF]]
|
|
// CHECK-NEXT: call swiftcc void @defaultC(ptr noalias swiftself %0, ptr %Self, ptr %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 ptr, ptr %SelfWitnessTable, i32 5
|
|
// CHECK-NEXT: [[WITNESS_FN:%.*]] = load ptr, ptr [[WITNESS_ADDR]]
|
|
// CHECK: call swiftcc void [[WITNESS_FN]](ptr noalias swiftself %0, ptr %Self, ptr %SelfWitnessTable)
|
|
%fn2 = witness_method $Self, #ResilientProtocol.defaultC : $@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: [[CONTEXT:%.*]] = call noalias ptr @swift_allocObject({{.*}})
|
|
// CHECK: [[WTABLE_ADDR:%.*]] = getelementptr inbounds{{.*}} <{ %swift.refcounted, [{{4|8}} x i8], ptr }>, ptr [[CONTEXT]], i32 0, i32 2
|
|
// CHECK-NEXT: store ptr %SelfWitnessTable, ptr [[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(ptr swiftself %0, ptr %Self, ptr %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 ptr
|
|
// CHECK-NEXT: store ptr %Self, ptr %[[SELF]]
|
|
// CHECK-NEXT: call swiftcc void @defaultF(ptr swiftself %0, ptr %Self, ptr %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 ptr, ptr %SelfWitnessTable, i32 8
|
|
// CHECK-NEXT: [[WITNESS_FN:%.*]] = load ptr, ptr [[WITNESS_ADDR]]
|
|
// CHECK: call swiftcc void [[WITNESS_FN]](ptr swiftself %0, ptr %Self, ptr %SelfWitnessTable)
|
|
%fn2 = witness_method $Self, #ResilientProtocol.defaultF : $@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: [[CONTEXT:%.*]] = call noalias ptr @swift_allocObject({{.*}})
|
|
// CHECK: [[WTABLE_ADDR:%.*]] = getelementptr inbounds{{.*}} <{ %swift.refcounted, [{{4|8}} x i8], ptr }>, ptr [[CONTEXT]], i32 0, i32 2
|
|
// CHECK-NEXT: store ptr %SelfWitnessTable, ptr [[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(ptr swiftself %0, ptr %Self, ptr %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 ptr
|
|
// CHECK-NEXT: store ptr %Self, ptr %[[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: @defaultC
|
|
method #ResilientProtocol.defaultD: @defaultD
|
|
method #ResilientProtocol.defaultE: @defaultE
|
|
method #ResilientProtocol.defaultF: @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(ptr noalias{{( nocapture)?}} swiftself{{( captures\(none\))?}} %0, ptr %Self, ptr %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: call swiftcc void @defaultC(ptr noalias swiftself %0, ptr %Self, ptr %SelfWitnessTable)
|
|
%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(ptr noalias{{( nocapture)?}} swiftself{{( captures\(none\))?}} %0, ptr %Self, ptr %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 ptr @swift_allocObject({{.*}})
|
|
// CHECK-NEXT: [[WTABLE:%.*]] = getelementptr inbounds{{.*}} <{ %swift.refcounted, ptr }>, ptr [[CONTEXT]], i32 0, i32 1
|
|
// CHECK-NEXT: store ptr %SelfWitnessTable, ptr [[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_conformance (T: OtherResilientProtocol): ResilientConformingType: OtherResilientProtocol module protocol_resilience
|
|
|
|
associated_type T: ResilientConformingType
|
|
method #ResilientProtocol.noDefaultA: @noDefaultA
|
|
method #ResilientProtocol.noDefaultB: @noDefaultB
|
|
method #ResilientProtocol.defaultC: @defaultC
|
|
method #ResilientProtocol.defaultD: @defaultD
|
|
method #ResilientProtocol.defaultE: @defaultE
|
|
method #ResilientProtocol.defaultF: @defaultF
|
|
}
|
|
|
|
|
|
//
|
|
// Make sure resilient conformances are accessed with an accessor function
|
|
//
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doSomething(ptr noalias %0, ptr %T, ptr %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(ptr noalias {{(nocapture|captures\(none\))}} %0)
|
|
sil @passConformingType : $@convention(thin) (@in ResilientConformingType) -> () {
|
|
bb0(%0 : $*ResilientConformingType):
|
|
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[WTABLE:%.*]] = call ptr @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWl"()
|
|
// CHECK-NEXT: call swiftcc void @doSomething(ptr noalias %0, ptr getelementptr inbounds ({{.*}} @"$s19protocol_resilience23ResilientConformingTypeVMf", i32 0, i32 2), ptr [[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 ptr @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWl"()
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[CACHE:%.*]] = load ptr, ptr @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWL"
|
|
// CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[CACHE]], null
|
|
// CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont
|
|
|
|
// CHECK: cacheIsNull:
|
|
// CHECK: [[WTABLE:%.*]] = call ptr @swift_getWitnessTable
|
|
// CHECK-NEXT: store atomic ptr [[WTABLE]], ptr @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWL" release
|
|
// CHECK-NEXT: br label %cont
|
|
|
|
// CHECK: cont:
|
|
// CHECK-NEXT: [[RESULT:%.*]] = phi ptr [ [[CCHE:%.*]], %entry ], [ [[WTABLE:%.*]], %cacheIsNull ]
|
|
// CHECK-NEXT: ret ptr [[RESULT]]
|
|
|
|
|
|
//
|
|
// 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(ptr noalias %0, ptr %T, ptr %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(ptr noalias {{(nocapture|captures\(none\))}} %0)
|
|
sil @passConformingTypeRefined : $@convention(thin) (@in AnotherConformingStruct) -> () {
|
|
bb0(%0 : $*AnotherConformingStruct):
|
|
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[WTABLE:%.*]] = call ptr @"$s19protocol_resilience23AnotherConformingStructVAcA29RefinesOtherResilientProtocolAAWl"()
|
|
// CHECK-NEXT: call swiftcc void @doSomethingRefined(ptr noalias %0, ptr getelementptr inbounds ({{.*}} @"$s19protocol_resilience23AnotherConformingStructVMf", i32 0, i32 2), ptr [[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_conformance (T: OtherResilientProtocol): ResilientConformingType: OtherResilientProtocol module protocol_resilience
|
|
associated_type T: ResilientConformingType
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doSomethingAssoc(ptr noalias %0, ptr %T, ptr %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(ptr noalias {{(nocapture|captures\(none\))}} %0)
|
|
sil @passConformingTypeAssoc : $@convention(thin) (@in ConformsWithResilientAssoc) -> () {
|
|
bb0(%0 : $*ConformsWithResilientAssoc):
|
|
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[WTABLE:%.*]] = call ptr @"$s19protocol_resilience26ConformsWithResilientAssocVAcA03HaseF0AAWl
|
|
// CHECK-NEXT: call swiftcc void @doSomethingAssoc(ptr noalias %0, ptr getelementptr inbounds ({{.*}} @"$s19protocol_resilience26ConformsWithResilientAssocVMf", i32 0, i32 2), ptr [[WTABLE]])
|
|
|
|
%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: @firstWitness
|
|
method #ProtocolWithRequirements.second: @secondWitness
|
|
}
|