Skip to content

Commit 68c4a6b

Browse files
authored
Merge pull request #16084 from DougGregor/witness-table-in-conformance-record-4.2-old
IRGen: Conformance records for dependent conformances should referenc…
2 parents e4c9d59 + 56a9c70 commit 68c4a6b

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
@@ -58,6 +58,7 @@
5858
#include "GenMeta.h"
5959
#include "GenObjC.h"
6060
#include "GenOpaque.h"
61+
#include "GenProto.h"
6162
#include "GenType.h"
6263
#include "IRGenDebugInfo.h"
6364
#include "IRGenFunction.h"
@@ -2728,31 +2729,29 @@ namespace {
27282729
void addWitnessTable() {
27292730
using ConformanceKind = ConformanceFlags::ConformanceKind;
27302731

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

27542753
witnessTableVar = IGM.getAddrOfWitnessTableAccessFunction(
2755-
Conformance, ForDefinition);
2754+
Conformance, ForDefinition);
27562755
}
27572756

27582757
// Relative reference to the witness table.

lib/IRGen/GenProto.cpp

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

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

951951
// Check whether any of the inherited conformances are dependent.
952952
for (auto inherited : conformance->getProtocol()->getInheritedProtocols()) {
953+
if (inherited->isObjC())
954+
continue;
955+
953956
if (isDependentConformance(IGM,
954957
conformance->getInheritedConformance(inherited)
955958
->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)