Skip to content

Commit d1da8f3

Browse files
committed
IRGen: Conformance records for dependent conformances should reference the witness table accessor function
... and not the pattern, which is about to get non-public linkage.
1 parent 9c30f4d commit d1da8f3

File tree

4 files changed

+47
-21
lines changed

4 files changed

+47
-21
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include "GenMeta.h"
6060
#include "GenObjC.h"
6161
#include "GenOpaque.h"
62+
#include "GenProto.h"
6263
#include "GenType.h"
6364
#include "IRGenDebugInfo.h"
6465
#include "IRGenFunction.h"
@@ -2730,31 +2731,29 @@ namespace {
27302731
void addWitnessTable() {
27312732
using ConformanceKind = ConformanceFlags::ConformanceKind;
27322733

2733-
// Figure out what kind of witness table we have.
2734-
auto proto = Conformance->getProtocol();
2734+
// Figure out what kind of witness table we have.
27352735
llvm::Constant *witnessTableVar;
2736-
if (!IGM.isResilient(proto, ResilienceExpansion::Maximal) &&
2737-
Conformance->getConditionalRequirements().empty()) {
2738-
Flags = Flags.withConformanceKind(ConformanceKind::WitnessTable);
2739-
2740-
// If the conformance is in this object's table, then the witness table
2741-
// should also be in this object file, so we can always directly
2742-
// reference it.
2743-
witnessTableVar = IGM.getAddrOfWitnessTable(Conformance);
2744-
} else {
2745-
if (Conformance->getConditionalRequirements().empty()) {
2736+
2737+
if (Conformance->getConditionalRequirements().empty()) {
2738+
if (!isDependentConformance(IGM, Conformance,
2739+
ResilienceExpansion::Maximal)) {
2740+
Flags = Flags.withConformanceKind(ConformanceKind::WitnessTable);
2741+
witnessTableVar = IGM.getAddrOfWitnessTable(Conformance);
2742+
} else {
27462743
Flags = Flags.withConformanceKind(
27472744
ConformanceKind::WitnessTableAccessor);
2748-
} else {
2749-
Flags =
2750-
Flags.withConformanceKind(
2751-
ConformanceKind::ConditionalWitnessTableAccessor)
2752-
.withNumConditionalRequirements(
2753-
Conformance->getConditionalRequirements().size());
2745+
witnessTableVar = IGM.getAddrOfWitnessTableAccessFunction(
2746+
Conformance, ForDefinition);
27542747
}
2748+
} else {
2749+
Flags =
2750+
Flags.withConformanceKind(
2751+
ConformanceKind::ConditionalWitnessTableAccessor)
2752+
.withNumConditionalRequirements(
2753+
Conformance->getConditionalRequirements().size());
27552754

27562755
witnessTableVar = IGM.getAddrOfWitnessTableAccessFunction(
2757-
Conformance, ForDefinition);
2756+
Conformance, ForDefinition);
27582757
}
27592758

27602759
// Relative reference to the witness table.

lib/IRGen/GenProto.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ static bool isResilientConformance(const NormalProtocolConformance *conformance)
937937

938938
/// Is there anything about the given conformance that requires witness
939939
/// tables to be dependently-generated?
940-
static bool isDependentConformance(IRGenModule &IGM,
940+
bool irgen::isDependentConformance(IRGenModule &IGM,
941941
const NormalProtocolConformance *conformance,
942942
ResilienceExpansion expansion) {
943943
// If the conformance is resilient, this is always true.
@@ -946,6 +946,9 @@ static bool isDependentConformance(IRGenModule &IGM,
946946

947947
// Check whether any of the inherited conformances are dependent.
948948
for (auto inherited : conformance->getProtocol()->getInheritedProtocols()) {
949+
if (inherited->isObjC())
950+
continue;
951+
949952
if (isDependentConformance(IGM,
950953
conformance->getInheritedConformance(inherited)
951954
->getRootNormalConformance(),

lib/IRGen/GenProto.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ namespace irgen {
255255
CanSILFunctionType fnType,
256256
GenericParamFulfillmentCallback callback);
257257

258+
bool isDependentConformance(IRGenModule &IGM,
259+
const NormalProtocolConformance *conformance,
260+
ResilienceExpansion expansion);
261+
258262
} // end namespace irgen
259263
} // end namespace swift
260264

test/IRGen/protocol_conformance_records.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@
44
import resilient_struct
55
import resilient_protocol
66

7+
public protocol Associate {
8+
associatedtype X
9+
}
10+
11+
// Dependent conformance
12+
// CHECK-LABEL: @"$S28protocol_conformance_records9DependentVyxGAA9AssociateAAMc" ={{ protected | }}constant
13+
// -- protocol descriptor
14+
// CHECK-SAME: @"$S28protocol_conformance_records9AssociateMp"
15+
// -- nominal type descriptor
16+
// CHECK-SAME: @"$S28protocol_conformance_records9DependentVMn"
17+
// -- witness table accessor
18+
// CHECK-SAME: @"$S28protocol_conformance_records9DependentVyxGAA9AssociateAAWa"
19+
// -- flags
20+
// CHECK-SAME: i32 1
21+
// CHECK-SAME: }
22+
public struct Dependent<T> {}
23+
24+
extension Dependent : Associate {
25+
public typealias X = (T, T)
26+
}
27+
728
public protocol Runcible {
829
func runce()
930
}
@@ -85,7 +106,6 @@ extension Size: Runcible {
85106
// CHECK-SAME: @"$S28protocol_conformance_records8RuncibleMp"
86107
// CHECK-SAME: @"$S28protocol_conformance_records5SpoonMp"
87108

88-
// TODO: conformances that need lazy initialization
89109
public protocol Spoon { }
90110

91111
// Conditional conformances

0 commit comments

Comments
 (0)