Skip to content

Commit a14ecfb

Browse files
committed
IRGen: Fix calls to default witnesses for static protocol requirements and factor out some duplication
We were checking for a @convention(witness_method) callee with an abstract Self type in several places. Factor this out into a new pair of methods on SILFunctionType, and fix the logic for static methods, where the Self archetype is wrapped in a metatype.
1 parent 5988e48 commit a14ecfb

File tree

6 files changed

+130
-66
lines changed

6 files changed

+130
-66
lines changed

include/swift/AST/Types.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3098,6 +3098,12 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
30983098
bool isPolymorphic() const { return GenericSig != nullptr; }
30993099
CanGenericSignature getGenericSignature() const { return GenericSig; }
31003100

3101+
CanType getSelfInstanceType() const;
3102+
3103+
/// If this a @convention(witness_method) function with an abstract
3104+
/// self parameter, return the protocol constraint for the Self type.
3105+
ProtocolDecl *getDefaultWitnessMethodProtocol(ModuleDecl &M) const;
3106+
31013107
ExtInfo getExtInfo() const { return ExtInfo(SILFunctionTypeBits.ExtInfo); }
31023108

31033109
/// \brief Returns the language-level calling convention of the function.
@@ -3119,8 +3125,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
31193125
}
31203126

31213127
CanSILFunctionType substGenericArgs(SILModule &silModule,
3122-
ModuleDecl *astModule,
3123-
ArrayRef<Substitution> subs);
3128+
ModuleDecl *astModule,
3129+
ArrayRef<Substitution> subs);
31243130

31253131
void Profile(llvm::FoldingSetNodeID &ID) {
31263132
Profile(ID, getGenericSignature(), getExtInfo(), getCalleeConvention(),

lib/IRGen/GenProto.cpp

Lines changed: 27 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,27 +1367,24 @@ namespace {
13671367
: M(M), FnType(fnType) {
13681368
initGenerics();
13691369

1370-
auto params = fnType->getParameters();
1371-
unsigned selfIndex = ~0U;
1372-
13731370
auto rep = fnType->getRepresentation();
13741371

13751372
if (rep == SILFunctionTypeRepresentation::WitnessMethod) {
13761373
// Protocol witnesses always derive all polymorphic parameter
13771374
// information from the Self argument. We also *cannot* consider other
13781375
// arguments; doing so would potentially make the signature
13791376
// incompatible with other witnesses for the same method.
1380-
selfIndex = params.size() - 1;
1381-
considerWitnessSelf(params[selfIndex], selfIndex);
1377+
considerWitnessSelf(fnType);
13821378
} else if (rep == SILFunctionTypeRepresentation::ObjCMethod) {
13831379
// Objective-C thunks for generic methods also always derive all
13841380
// polymorphic parameter information from the Self argument.
1385-
selfIndex = params.size() - 1;
1386-
considerObjCGenericSelf(params[selfIndex], selfIndex);
1381+
considerObjCGenericSelf(fnType);
13871382
} else {
13881383
// We don't need to pass anything extra as long as all of the
13891384
// archetypes (and their requirements) are producible from
13901385
// arguments.
1386+
unsigned selfIndex = ~0U;
1387+
auto params = fnType->getParameters();
13911388

13921389
// Consider 'self' first.
13931390
if (fnType->hasSelfParam()) {
@@ -1527,24 +1524,21 @@ namespace {
15271524

15281525
/// Testify to generic parameters in the Self type of a protocol
15291526
/// witness method.
1530-
void considerWitnessSelf(SILParameterInfo param, unsigned paramIndex) {
1531-
// If this is a static method, get the instance type.
1532-
CanType selfTy = param.getType();
1533-
if (auto metaTy = dyn_cast<AnyMetatypeType>(selfTy))
1534-
selfTy = metaTy.getInstanceType();
1527+
void considerWitnessSelf(CanSILFunctionType fnType) {
1528+
CanType selfTy = fnType->getSelfInstanceType();
15351529

15361530
// First, bind type metadata for Self.
15371531
Sources.emplace_back(SourceKind::SelfMetadata, InvalidSourceIndex,
15381532
selfTy);
15391533

1540-
if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
1534+
if (auto *proto = fnType->getDefaultWitnessMethodProtocol(M)) {
15411535
// The Self type is abstract, so we must pass in a witness table.
1542-
addSelfMetadataFulfillment(paramTy);
1536+
addSelfMetadataFulfillment(selfTy);
15431537

15441538
// Look at the witness table for the conformance.
15451539
Sources.emplace_back(SourceKind::SelfWitnessTable, InvalidSourceIndex,
15461540
selfTy);
1547-
addSelfWitnessTableFulfillment(paramTy);
1541+
addSelfWitnessTableFulfillment(selfTy, proto);
15481542
} else {
15491543
// If the Self type is concrete, we have a witness thunk with a
15501544
// fully substituted Self type. The witness table parameter is not
@@ -1555,18 +1549,17 @@ namespace {
15551549

15561550
/// Testify to generic parameters in the Self type of an @objc
15571551
/// generic or protocol method.
1558-
void considerObjCGenericSelf(SILParameterInfo param, unsigned paramIndex) {
1552+
void considerObjCGenericSelf(CanSILFunctionType fnType) {
15591553
// If this is a static method, get the instance type.
1560-
CanType selfTy = param.getType();
1561-
if (auto metaTy = dyn_cast<AnyMetatypeType>(selfTy))
1562-
selfTy = metaTy.getInstanceType();
1554+
CanType selfTy = fnType->getSelfInstanceType();
1555+
unsigned paramIndex = fnType->getParameters().size() - 1;
15631556

15641557
// Bind type metadata for Self.
15651558
Sources.emplace_back(SourceKind::ClassPointer, paramIndex,
15661559
selfTy);
15671560

1568-
if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy))
1569-
addSelfMetadataFulfillment(paramTy);
1561+
if (isa<GenericTypeParamType>(selfTy))
1562+
addSelfMetadataFulfillment(selfTy);
15701563
else
15711564
considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath());
15721565
}
@@ -1616,23 +1609,14 @@ namespace {
16161609
llvm_unreachable("bad parameter convention");
16171610
}
16181611

1619-
void addSelfMetadataFulfillment(CanGenericTypeParamType arg) {
1620-
assert(arg->getDepth() == 0 && arg->getIndex() == 0);
1621-
1612+
void addSelfMetadataFulfillment(CanType arg) {
16221613
unsigned source = Sources.size() - 1;
16231614
Fulfillments.addFulfillment({arg, nullptr}, source, MetadataPath());
16241615
}
16251616

1626-
void addSelfWitnessTableFulfillment(CanGenericTypeParamType arg) {
1627-
assert(arg->getDepth() == 0 && arg->getIndex() == 0);
1628-
1617+
void addSelfWitnessTableFulfillment(CanType arg, ProtocolDecl *proto) {
16291618
unsigned source = Sources.size() - 1;
1630-
auto protos = getConformsTo(arg);
1631-
assert(protos.size() == 1);
1632-
for (auto protocol : protos) {
1633-
//considerWitnessTable(arg, protocol, Sources.size() - 1, MetadataPath());
1634-
Fulfillments.addFulfillment({arg, protocol}, source, MetadataPath());
1635-
}
1619+
Fulfillments.addFulfillment({arg, proto}, source, MetadataPath());
16361620
}
16371621
};
16381622

@@ -1684,9 +1668,10 @@ namespace {
16841668
assert(witnessMetadata && "no metadata for witness method");
16851669
llvm::Value *metadata = witnessMetadata->SelfMetadata;
16861670
assert(metadata && "no Self metadata for witness method");
1687-
1671+
16881672
// Mark this as the cached metatype for Self.
1689-
CanType argTy = getArgTypeInContext(FnType->getParameters().size() - 1);
1673+
auto selfTy = FnType->getSelfInstanceType();
1674+
CanType argTy = getTypeInContext(selfTy);
16901675
setTypeMetadataName(IGF.IGM, metadata, argTy);
16911676
IGF.bindLocalTypeDataFromTypeMetadata(argTy, IsExact, metadata);
16921677
return;
@@ -1698,16 +1683,15 @@ namespace {
16981683
assert(wtable && "no Self witness table for witness method");
16991684

17001685
// Mark this as the cached witness table for Self.
1701-
CanType argTy = getArgTypeInContext(FnType->getParameters().size() - 1);
17021686

1703-
if (auto archetypeTy = dyn_cast<ArchetypeType>(argTy)) {
1704-
auto protos = archetypeTy->getConformsTo();
1705-
assert(protos.size() == 1);
1706-
auto *protocol = protos[0];
1687+
if (auto *proto = FnType->getDefaultWitnessMethodProtocol(M)) {
1688+
auto selfTy = FnType->getSelfInstanceType();
1689+
CanType argTy = getTypeInContext(selfTy);
1690+
auto archetype = cast<ArchetypeType>(argTy);
17071691

1708-
setProtocolWitnessTableName(IGF.IGM, wtable, argTy, protocol);
1709-
IGF.setUnscopedLocalTypeData(CanType(archetypeTy),
1710-
LocalTypeDataKind::forAbstractProtocolWitnessTable(protocol),
1692+
setProtocolWitnessTableName(IGF.IGM, wtable, argTy, proto);
1693+
IGF.setUnscopedLocalTypeData(archetype,
1694+
LocalTypeDataKind::forAbstractProtocolWitnessTable(proto),
17111695
wtable);
17121696
}
17131697
return;

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,29 +1844,22 @@ static llvm::Value *getObjCClassForValue(IRGenSILFunction &IGF,
18441844
static llvm::Value *emitWitnessTableForLoweredCallee(IRGenSILFunction &IGF,
18451845
CanSILFunctionType origCalleeType,
18461846
ArrayRef<Substitution> subs) {
1847+
auto &M = *IGF.IGM.SILMod->getSwiftModule();
18471848
llvm::Value *wtable;
18481849

1849-
// The type of the self parameter in the witness. This may be abstract
1850-
// or concrete.
1851-
CanType origSelfType = origCalleeType->getSelfParameter().getType();
1852-
1853-
if (auto genericParamType = dyn_cast<GenericTypeParamType>(origSelfType)) {
1850+
if (auto *proto = origCalleeType->getDefaultWitnessMethodProtocol(M)) {
18541851
// The generic signature for a witness method with abstract Self must
18551852
// have exactly one protocol requirement.
18561853
//
18571854
// We recover the witness table from the substitution that was used to
18581855
// produce the substituted callee type.
1859-
assert(genericParamType->getDepth() == 0);
1860-
assert(genericParamType->getIndex() == 0);
1861-
(void) genericParamType;
1862-
1856+
//
18631857
// There can be multiple substitutions, but the first one is the Self type.
18641858
assert(subs.size() >= 1);
18651859
assert(subs[0].getConformances().size() == 1);
18661860

18671861
auto conformance = subs[0].getConformances()[0];
18681862
auto substSelfType = subs[0].getReplacement()->getCanonicalType();
1869-
auto *proto = conformance.getRequirement();
18701863

18711864
llvm::Value *argMetadata = IGF.emitTypeMetadataRef(substSelfType);
18721865
wtable = emitWitnessTableRef(IGF, substSelfType, &argMetadata,

lib/SIL/SILFunctionType.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,30 @@ SILType SILFunctionType::getCSemanticResult() {
6767
}
6868
}
6969

70+
CanType SILFunctionType::getSelfInstanceType() const {
71+
auto selfTy = getSelfParameter().getType();
72+
73+
// If this is a static method, get the instance type.
74+
if (auto metaTy = dyn_cast<AnyMetatypeType>(selfTy))
75+
return metaTy.getInstanceType();
76+
77+
return selfTy;
78+
}
79+
80+
ProtocolDecl *
81+
SILFunctionType::getDefaultWitnessMethodProtocol(ModuleDecl &M) const {
82+
assert(getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod);
83+
auto selfTy = getSelfInstanceType();
84+
if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
85+
assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
86+
auto protos = GenericSig->getConformsTo(paramTy, M);
87+
assert(protos.size() == 1);
88+
return protos[0];
89+
}
90+
91+
return nullptr;
92+
}
93+
7094
static CanType getKnownType(Optional<CanType> &cacheSlot, ASTContext &C,
7195
StringRef moduleName, StringRef typeName) {
7296
if (!cacheSlot) {

test/IRGen/protocol_resilience.sil

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import resilient_protocol
2222
// CHECK: @_TMp19protocol_resilience17ResilientProtocol = {{(protected )?}}constant <{{.*}}> <{
2323
// CHECK-SAME: i32 1031,
2424
// CHECK-SAME: i16 2,
25-
// CHECK-SAME: i16 2,
25+
// CHECK-SAME: i16 4,
2626
// CHECK-SAME: void (%swift.opaque*, %swift.type*, i8**)* @defaultC,
2727
// CHECK-SAME: void (%swift.opaque*, %swift.type*, i8**)* @defaultD
2828
// CHECK-SAME: }>
@@ -35,6 +35,8 @@ public protocol ResilientProtocol {
3535
func noDefaultB()
3636
func defaultC()
3737
func defaultD()
38+
static func defaultE()
39+
static func defaultF()
3840
}
3941

4042

@@ -69,7 +71,6 @@ sil @defaultD : $@convention(witness_method) <Self where Self : ResilientProtoco
6971
bb0(%0 : $*Self):
7072

7173
// Make sure we can emit direct references to other default implementations
72-
// (SILGen will never emit this, but the devirtualizer might)
7374

7475
// CHECK-NEXT: call void @defaultC(%swift.opaque* noalias nocapture %0, %swift.type* %Self, i8** %SelfWitnessTable)
7576
%fn1 = function_ref @defaultC : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
@@ -103,12 +104,65 @@ bb0(%0 : $*Self):
103104
}
104105

105106

107+
// CHECK-LABEL: define{{( protected)?}} void @defaultE(%swift.type*, %swift.type* %Self, i8** %SelfWitnessTable)
108+
// CHECK-NEXT: entry:
109+
110+
sil @defaultE : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> () {
111+
bb0(%0 : $@thick Self.Type):
112+
113+
// Make sure we can emit direct references to other default implementations
114+
115+
// CHECK-NEXT: call void @defaultF(%swift.type* %0, %swift.type* %Self, i8** %SelfWitnessTable)
116+
%fn1 = function_ref @defaultF : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
117+
%ignore1 = apply %fn1<Self, Self.T>(%0) : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
118+
119+
// Make sure we can do dynamic dispatch to other protocol requirements
120+
// from a default implementation
121+
122+
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %SelfWitnessTable, i32 7
123+
// CHECK-NEXT: [[WITNESS_FN:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
124+
// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[WITNESS_FN]] to void (%swift.type*, %swift.type*, i8**)*
125+
// CHECK-NEXT: call void [[WITNESS]](%swift.type* %0, %swift.type* %Self, i8** %SelfWitnessTable)
126+
%fn2 = witness_method $Self, #ResilientProtocol.defaultF!1 : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
127+
%ignore2 = apply %fn2<Self, Self.T>(%0) : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
128+
129+
// Make sure we can partially apply a static reference to a default
130+
// implementation
131+
132+
// CHECK-NEXT: [[WTABLE:%.*]] = bitcast i8** %SelfWitnessTable to i8*
133+
// CHECK-NEXT: [[CONTEXT:%.*]] = call noalias %swift.refcounted* @swift_allocObject({{.*}})
134+
// CHECK-NEXT: [[LAYOUT:%.*]] = bitcast %swift.refcounted* [[CONTEXT]] to <{ %swift.refcounted, [{{4|8}} x i8], i8* }>*
135+
// CHECK: [[WTABLE_ADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [{{4|8}} x i8], i8* }>, <{ %swift.refcounted, [{{4|8}} x i8], i8* }>* [[LAYOUT]], i32 0, i32 2
136+
// CHECK-NEXT: store i8* [[WTABLE]], i8** [[WTABLE_ADDR]]
137+
138+
%fn3 = function_ref @defaultF : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
139+
%ignore3 = partial_apply %fn3<Self, Self.T>() : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> ()
140+
141+
// CHECK-NEXT: ret void
142+
%result = tuple ()
143+
return %result : $()
144+
}
145+
146+
147+
// CHECK-LABEL: define{{( protected)?}} void @defaultF(%swift.type*, %swift.type* %Self, i8** %SelfWitnessTable)
148+
// CHECK-NEXT: entry:
149+
150+
sil @defaultF : $@convention(witness_method) <Self where Self : ResilientProtocol> (@thick Self.Type) -> () {
151+
bb0(%0 : $@thick Self.Type):
152+
153+
// CHECK-NEXT: ret void
154+
%result = tuple ()
155+
return %result : $()
156+
}
157+
158+
106159
sil_default_witness_table ResilientProtocol 2 {
107160
method #ResilientProtocol.defaultC!1: @defaultC
108161
method #ResilientProtocol.defaultD!1: @defaultD
162+
method #ResilientProtocol.defaultE!1: @defaultE
163+
method #ResilientProtocol.defaultF!1: @defaultF
109164
}
110165

111-
112166
public struct ResilientConformingType : OtherResilientProtocol {}
113167

114168
sil_witness_table ResilientConformingType : OtherResilientProtocol module protocol_resilience {}
@@ -120,6 +174,8 @@ struct ConformingStruct : ResilientProtocol {
120174
func noDefaultB()
121175
func defaultC()
122176
func defaultD()
177+
static func defaultE()
178+
static func defaultF()
123179
}
124180

125181
// CHECK-LABEL: define{{( protected)?}} void @noDefaultA(%V19protocol_resilience16ConformingStruct* noalias nocapture, %swift.type* %Self, i8** %SelfWitnessTable)
@@ -129,11 +185,10 @@ sil @noDefaultA : $@convention(witness_method) (@in_guaranteed ConformingStruct)
129185
bb0(%0 : $*ConformingStruct):
130186

131187
// Make sure we can emit direct references to default implementations with a
132-
// concrete Self type (SILGen will never emit this, but the devirtualizer
133-
// might)
188+
// concrete Self type.
134189

135190
// CHECK-NEXT: [[SELF:%.*]] = bitcast %V19protocol_resilience16ConformingStruct* %0 to %swift.opaque*
136-
// CHECK-NEXT: call void @defaultC(%swift.opaque* noalias nocapture [[SELF]], %swift.type* bitcast ({{i32|i64}}* {{.*}}) to %swift.type*), i8** getelementptr inbounds ([6 x i8*], [6 x i8*]* @_TWPV19protocol_resilience16ConformingStructS_17ResilientProtocolS_, i32 0, i32 0))
191+
// CHECK-NEXT: call void @defaultC(%swift.opaque* noalias nocapture [[SELF]], %swift.type* bitcast ({{i32|i64}}* {{.*}}) to %swift.type*), i8** getelementptr inbounds ([8 x i8*], [8 x i8*]* @_TWPV19protocol_resilience16ConformingStructS_17ResilientProtocolS_, i32 0, i32 0))
137192
%fn1 = function_ref @defaultC : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
138193
%ignore1 = apply %fn1<ConformingStruct, ResilientConformingType>(%0) : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
139194

@@ -154,7 +209,7 @@ bb0(%0 : $*ConformingStruct):
154209
// CHECK-NEXT: [[CONTEXT:%.*]] = call noalias %swift.refcounted* @swift_allocObject({{.*}})
155210
// CHECK-NEXT: [[LAYOUT:%.*]] = bitcast %swift.refcounted* [[CONTEXT]] to <{ %swift.refcounted, i8* }>*
156211
// CHECK-NEXT: [[WTABLE:%.*]] = getelementptr inbounds <{ %swift.refcounted, i8* }>, <{ %swift.refcounted, i8* }>* [[LAYOUT]], i32 0, i32 1
157-
// CHECK-NEXT: store i8* bitcast ([6 x i8*]* @_TWPV19protocol_resilience16ConformingStructS_17ResilientProtocolS_ to i8*), i8** [[WTABLE]]
212+
// CHECK-NEXT: store i8* bitcast ([8 x i8*]* @_TWPV19protocol_resilience16ConformingStructS_17ResilientProtocolS_ to i8*), i8** [[WTABLE]]
158213

159214
%fn1 = function_ref @defaultC : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
160215
%ignore1 = partial_apply %fn1<ConformingStruct, ResilientConformingType>() : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> ()
@@ -172,6 +227,8 @@ sil_witness_table ConformingStruct : ResilientProtocol module protocol_resilienc
172227
method #ResilientProtocol.noDefaultB!1: @noDefaultB
173228
method #ResilientProtocol.defaultC!1: @defaultC
174229
method #ResilientProtocol.defaultD!1: @defaultD
230+
method #ResilientProtocol.defaultE!1: @defaultE
231+
method #ResilientProtocol.defaultF!1: @defaultF
175232
}
176233

177234

@@ -320,4 +377,4 @@ bb0(%0 : $*ConformsWithResilientAssoc):
320377

321378
// CHECK-LABEL: define{{( protected)?}} i8** @_TWaV19protocol_resilience16ConformingStructS_17ResilientProtocolS_()
322379
// CHECK-NEXT: entry:
323-
// CHECK-NEXT: ret i8** getelementptr inbounds ([6 x i8*], [6 x i8*]* @_TWPV19protocol_resilience16ConformingStructS_17ResilientProtocolS_, i32 0, i32 0)
380+
// CHECK-NEXT: ret i8** getelementptr inbounds ([8 x i8*], [8 x i8*]* @_TWPV19protocol_resilience16ConformingStructS_17ResilientProtocolS_, i32 0, i32 0)

test/IRGen/sil_witness_methods.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ entry(%x : $@thick Foo.Type):
5757

5858
// The use of %0 or %Self here is irrelevant.
5959
// CHECK-LABEL: define{{( protected)?}} %swift.type* @generic_type_concrete_static_method_witness(%swift.type*, %swift.type* %Self, i8** %SelfWitnessTable)
60-
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type**
60+
// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type**
6161
// CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 10
6262
// CHECK: %T = load %swift.type*, %swift.type** [[T1]], align 8
63-
// CHECK: [[U0:%.*]] = bitcast %swift.type* %0 to %swift.type**
63+
// CHECK: [[U0:%.*]] = bitcast %swift.type* %Self to %swift.type**
6464
// CHECK: [[U1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[U0]], i64 11
6565
// CHECK: %U = load %swift.type*, %swift.type** [[U1]], align 8
66-
// CHECK: [[V0:%.*]] = bitcast %swift.type* %0 to %swift.type**
66+
// CHECK: [[V0:%.*]] = bitcast %swift.type* %Self to %swift.type**
6767
// CHECK: [[V1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[V0]], i64 12
6868
// CHECK: %V = load %swift.type*, %swift.type** [[V1]], align 8
6969
sil @generic_type_concrete_static_method_witness : $@convention(witness_method) <T, U, V> (@thick Bar<T, U, V>.Type) -> @thick Bar<T, U, V>.Type {

0 commit comments

Comments
 (0)