Skip to content

Commit 6a3ead3

Browse files
authored
Merge pull request #80107 from slavapestov/for-abstract-conformance
Fix a few more callers of ProtocolConformanceRef::forAbstract() to pass in a subject type
2 parents c28279f + 9c657e4 commit 6a3ead3

26 files changed

+183
-127
lines changed

SwiftCompilerSources/Sources/AST/Conformance.swift

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public struct Conformance: CustomStringConvertible, NoReflectionChildren {
3737
return Type(bridged: bridged.getType())
3838
}
3939

40+
public var proto: ProtocolDecl {
41+
return bridged.getRequirement().getAs(ProtocolDecl.self)
42+
}
4043
public var isSpecialized: Bool {
4144
assert(isConcrete)
4245
return bridged.isSpecializedConformance()

SwiftCompilerSources/Sources/Optimizer/Utilities/GenericSpecialization.swift

+6-3
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,17 @@ func specializeWitnessTable(forConformance conformance: Conformance,
144144
case .associatedType(let requirement, let witness):
145145
let substType = witness.subst(with: conformance.specializedSubstitutions)
146146
return .associatedType(requirement: requirement, witness: substType)
147-
case .associatedConformance(let requirement, let proto, _):
148-
let concreteAssociateConf = conformance.getAssociatedConformance(ofAssociatedType: requirement.rawType, to: proto)
147+
case .associatedConformance(let requirement, let substType, let assocConf):
148+
// FIXME: let concreteAssociateConf = assocConf.subst(with: conformance.specializedSubstitutions)
149+
let concreteAssociateConf = conformance.getAssociatedConformance(ofAssociatedType: requirement.rawType, to: assocConf.proto)
149150
if concreteAssociateConf.isSpecialized {
150151
specializeWitnessTable(forConformance: concreteAssociateConf,
151152
errorLocation: errorLocation,
152153
context, notifyNewWitnessTable)
153154
}
154-
return .associatedConformance(requirement: requirement, protocol: proto, witness: concreteAssociateConf)
155+
return .associatedConformance(requirement: requirement,
156+
substType: substType.subst(with: conformance.specializedSubstitutions),
157+
witness: concreteAssociateConf)
155158
}
156159
}
157160
let newWT = context.createWitnessTable(entries: newEntries,conformance: conformance,

SwiftCompilerSources/Sources/SIL/WitnessTable.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public struct WitnessTable : CustomStringConvertible, NoReflectionChildren {
3131
case associatedType(requirement: AssociatedTypeDecl, witness: CanonicalType)
3232

3333
/// A witness table entry describing the witness for an associated type's protocol requirement.
34-
case associatedConformance(requirement: CanonicalType, protocol: ProtocolDecl, witness: Conformance)
34+
case associatedConformance(requirement: CanonicalType, substType: CanonicalType, witness: Conformance)
3535

3636
/// A witness table entry referencing the protocol conformance for a refined base protocol.
3737
case baseProtocol(requirement: ProtocolDecl, witness: Conformance)
@@ -48,7 +48,7 @@ public struct WitnessTable : CustomStringConvertible, NoReflectionChildren {
4848
witness: CanonicalType(bridged: bridged.getAssociatedTypeWitness()))
4949
case .associatedConformance:
5050
self = .associatedConformance(requirement: CanonicalType(bridged: bridged.getAssociatedConformanceRequirement()),
51-
protocol: bridged.getAssociatedConformanceDecl().getAs(ProtocolDecl.self),
51+
substType: CanonicalType(bridged: bridged.getAssociatedConformanceSubstType()),
5252
witness: Conformance(bridged: bridged.getAssociatedConformanceWitness()))
5353
case .baseProtocol:
5454
self = .baseProtocol(requirement: bridged.getBaseProtocolRequirement().getAs(ProtocolDecl.self),
@@ -71,9 +71,9 @@ public struct WitnessTable : CustomStringConvertible, NoReflectionChildren {
7171
OptionalBridgedFunction(obj: witness?.bridged.obj))
7272
case .associatedType(let requirement, let witness):
7373
return BridgedWitnessTableEntry.createAssociatedType(requirement.bridged, witness.bridged)
74-
case .associatedConformance(let requirement, let protocolDecl, let witness):
74+
case .associatedConformance(let requirement, let substType, let witness):
7575
return BridgedWitnessTableEntry.createAssociatedConformance(requirement.bridged,
76-
protocolDecl.bridged,
76+
substType.bridged,
7777
witness.bridged)
7878
case .baseProtocol(let requirement, let witness):
7979
return BridgedWitnessTableEntry.createBaseProtocol(requirement.bridged, witness.bridged)

include/swift/AST/ASTBridging.h

+1
Original file line numberDiff line numberDiff line change
@@ -3110,6 +3110,7 @@ struct BridgedConformance {
31103110
BRIDGED_INLINE bool isSpecializedConformance() const;
31113111
BRIDGED_INLINE bool isInheritedConformance() const;
31123112
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedASTType getType() const;
3113+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getRequirement() const;
31133114
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance getGenericConformance() const;
31143115
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance getInheritedConformance() const;
31153116
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedSubstitutionMap getSpecializedSubstitutions() const;

include/swift/AST/ASTBridgingImpl.h

+4
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,10 @@ BridgedASTType BridgedConformance::getType() const {
601601
return {unbridged().getConcrete()->getType().getPointer()};
602602
}
603603

604+
BridgedDeclObj BridgedConformance::getRequirement() const {
605+
return {unbridged().getRequirement()};
606+
}
607+
604608
BridgedConformance BridgedConformance::getGenericConformance() const {
605609
auto *specPC = swift::cast<swift::SpecializedProtocolConformance>(unbridged().getConcrete());
606610
return {swift::ProtocolConformanceRef(specPC->getGenericConformance())};

include/swift/AST/ProtocolConformanceRef.h

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/ProtocolConformanceRef.h"
2020
#include "swift/AST/Type.h"
2121
#include "swift/AST/TypeAlignments.h"
22+
#include "swift/Basic/Assertions.h"
2223
#include "swift/Basic/Debug.h"
2324
#include "llvm/ADT/Hashing.h"
2425
#include "llvm/ADT/PointerUnion.h"
@@ -101,13 +102,15 @@ class ProtocolConformanceRef {
101102
return !isInvalid() && Union.is<ProtocolConformance*>();
102103
}
103104
ProtocolConformance *getConcrete() const {
105+
ASSERT(isConcrete());
104106
return Union.get<ProtocolConformance*>();
105107
}
106108

107109
bool isPack() const {
108110
return !isInvalid() && Union.is<PackConformance*>();
109111
}
110112
PackConformance *getPack() const {
113+
ASSERT(isPack());
111114
return Union.get<PackConformance*>();
112115
}
113116

@@ -116,6 +119,7 @@ class ProtocolConformanceRef {
116119
}
117120

118121
ProtocolDecl *getAbstract() const {
122+
ASSERT(isAbstract());
119123
return Union.get<ProtocolDecl*>();
120124
}
121125

include/swift/SIL/SILBridging.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ struct BridgedWitnessTableEntry {
10071007
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getAssociatedTypeRequirement() const;
10081008
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCanType getAssociatedTypeWitness() const;
10091009
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCanType getAssociatedConformanceRequirement() const;
1010-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getAssociatedConformanceDecl() const;
1010+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCanType getAssociatedConformanceSubstType() const;
10111011
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance getAssociatedConformanceWitness() const;
10121012
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getBaseProtocolRequirement() const;
10131013
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance getBaseProtocolWitness() const;
@@ -1022,7 +1022,7 @@ struct BridgedWitnessTableEntry {
10221022
BridgedCanType witness);
10231023
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
10241024
static BridgedWitnessTableEntry createAssociatedConformance(BridgedCanType requirement,
1025-
BridgedDeclObj protocolDecl,
1025+
BridgedCanType substType,
10261026
BridgedConformance witness);
10271027
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
10281028
static BridgedWitnessTableEntry createBaseProtocol(BridgedDeclObj requirement,

include/swift/SIL/SILBridgingImpl.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -1832,8 +1832,8 @@ BridgedCanType BridgedWitnessTableEntry::getAssociatedConformanceRequirement() c
18321832
return unbridged().getAssociatedConformanceWitness().Requirement;
18331833
}
18341834

1835-
BridgedDeclObj BridgedWitnessTableEntry::getAssociatedConformanceDecl() const {
1836-
return {unbridged().getAssociatedConformanceWitness().Protocol};
1835+
BridgedCanType BridgedWitnessTableEntry::getAssociatedConformanceSubstType() const {
1836+
return {unbridged().getAssociatedConformanceWitness().SubstType};
18371837
}
18381838

18391839
BridgedConformance BridgedWitnessTableEntry::getAssociatedConformanceWitness() const {
@@ -1867,11 +1867,11 @@ BridgedWitnessTableEntry BridgedWitnessTableEntry::createAssociatedType(BridgedD
18671867
}
18681868

18691869
BridgedWitnessTableEntry BridgedWitnessTableEntry::createAssociatedConformance(BridgedCanType requirement,
1870-
BridgedDeclObj protocolDecl,
1870+
BridgedCanType substType,
18711871
BridgedConformance witness) {
18721872
return bridge(swift::SILWitnessTable::Entry(
18731873
swift::SILWitnessTable::AssociatedConformanceWitness{requirement.unbridged(),
1874-
protocolDecl.getAs<swift::ProtocolDecl>(),
1874+
substType.unbridged(),
18751875
witness.unbridged()}));
18761876
}
18771877

include/swift/SIL/SILWitnessTable.h

+5-6
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,11 @@ class SILWitnessTable : public llvm::ilist_node<SILWitnessTable>,
6464
/// A witness table entry describing the witness for an associated type's
6565
/// protocol requirement.
6666
struct AssociatedConformanceWitness {
67-
/// The associated type required. A dependent type in the protocol's
68-
/// context.
67+
/// The subject type of the associated requirement.
6968
CanType Requirement;
70-
/// The protocol requirement on the type.
71-
ProtocolDecl *Protocol;
72-
/// The ProtocolConformance satisfying the requirement. Null if the
73-
/// conformance is dependent.
69+
/// FIXME: Temporary.
70+
CanType SubstType;
71+
/// The ProtocolConformanceRef satisfying the requirement.
7472
ProtocolConformanceRef Witness;
7573
};
7674

@@ -160,6 +158,7 @@ class SILWitnessTable : public llvm::ilist_node<SILWitnessTable>,
160158
/// conditional. These aren't public, but any witness thunks need to feed them
161159
/// into the true witness functions.
162160
struct ConditionalConformance {
161+
/// FIXME: Temporary.
163162
CanType Requirement;
164163
ProtocolConformanceRef Conformance;
165164
};

lib/AST/ProtocolConformanceRef.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ bool ProtocolConformanceRef::isInvalid() const {
4949
}
5050

5151
ProtocolDecl *ProtocolConformanceRef::getRequirement() const {
52-
assert(!isInvalid());
53-
5452
if (isConcrete()) {
5553
return getConcrete()->getProtocol();
5654
} else if (isPack()) {

lib/IRGen/GenMeta.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -1182,14 +1182,17 @@ namespace {
11821182

11831183
for (auto &entry : DefaultWitnesses->getEntries()) {
11841184
if (!entry.isValid() ||
1185-
entry.getKind() != SILWitnessTable::AssociatedConformance ||
1186-
entry.getAssociatedConformanceWitness().Protocol != requirement ||
1187-
entry.getAssociatedConformanceWitness().Requirement != association)
1185+
entry.getKind() != SILWitnessTable::AssociatedConformance)
1186+
continue;
1187+
1188+
auto assocConf = entry.getAssociatedConformanceWitness();
1189+
if (assocConf.Requirement != association ||
1190+
assocConf.Witness.getRequirement() != requirement)
11881191
continue;
11891192

1190-
auto witness = entry.getAssociatedConformanceWitness().Witness;
11911193
AssociatedConformance conformance(Proto, association, requirement);
1192-
defineDefaultAssociatedConformanceAccessFunction(conformance, witness);
1194+
defineDefaultAssociatedConformanceAccessFunction(
1195+
conformance, assocConf.Witness);
11931196
return IGM.getMangledAssociatedConformance(nullptr, conformance);
11941197
}
11951198

lib/IRGen/GenProto.cpp

+16-19
Original file line numberDiff line numberDiff line change
@@ -1780,9 +1780,6 @@ class AccessorConformanceInfo : public ConformanceInfo {
17801780
auto associatedWitness = entry.getAssociatedConformanceWitness();
17811781
assert(associatedWitness.Requirement == requirement.getAssociation()
17821782
&& "sil witness table does not match protocol");
1783-
assert(associatedWitness.Protocol ==
1784-
requirement.getAssociatedRequirement()
1785-
&& "sil witness table does not match protocol");
17861783
auto piIndex = PI.getAssociatedConformanceIndex(requirement);
17871784
assert((size_t)piIndex.getValue() ==
17881785
Table.size() - WitnessTableFirstRequirementOffset &&
@@ -1792,10 +1789,8 @@ class AccessorConformanceInfo : public ConformanceInfo {
17921789
if (IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
17931790
// In Embedded Swift associated-conformance entries simply point to the witness table
17941791
// of the associated conformance.
1795-
ProtocolConformanceRef assocConf =
1796-
SILWT->getConformance()->getAssociatedConformance(requirement.getAssociation(),
1797-
requirement.getAssociatedRequirement());
1798-
llvm::Constant *witnessEntry = IGM.getAddrOfWitnessTable(assocConf.getConcrete());
1792+
ProtocolConformance *assocConf = associatedWitness.Witness.getConcrete();
1793+
llvm::Constant *witnessEntry = IGM.getAddrOfWitnessTable(assocConf);
17991794
auto &schema = IGM.getOptions().PointerAuth
18001795
.ProtocolAssociatedTypeWitnessTableAccessFunctions;
18011796
Table.addSignedPointer(witnessEntry, schema, requirement);
@@ -2030,10 +2025,11 @@ void ResilientWitnessTableBuilder::collectResilientWitnesses(
20302025

20312026
ProtocolConformanceRef associatedConformance =
20322027
ConformanceInContext.getAssociatedConformance(witness.Requirement,
2033-
witness.Protocol);
2028+
witness.Witness.getRequirement());
2029+
20342030
AssociatedConformance requirement(SILWT->getProtocol(),
20352031
witness.Requirement,
2036-
witness.Protocol);
2032+
witness.Witness.getRequirement());
20372033

20382034
llvm::Constant *witnessEntry =
20392035
getAssociatedConformanceWitness(requirement, associate,
@@ -2353,7 +2349,7 @@ namespace {
23532349

23542350
AssociatedConformance requirement(SILWT->getProtocol(),
23552351
witness.Requirement,
2356-
witness.Protocol);
2352+
witness.Witness.getRequirement());
23572353
auto assocConformanceDescriptor =
23582354
IGM.getAddrOfLLVMVariableOrGOTEquivalent(
23592355
LinkEntity::forAssociatedConformanceDescriptor(requirement));
@@ -3402,8 +3398,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
34023398
}
34033399

34043400
case Component::Kind::OutOfLineBaseProtocol: {
3405-
auto conformance = sourceKey.Kind.getProtocolConformance();
3406-
auto protocol = conformance.getRequirement();
3401+
auto protocol = sourceKey.Kind.getConformedProtocol();
34073402
auto &pi = IGF.IGM.getProtocolInfo(protocol,
34083403
ProtocolInfoKind::RequirementSignature);
34093404

@@ -3413,9 +3408,10 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
34133408

34143409
sourceKey.Kind =
34153410
LocalTypeDataKind::forAbstractProtocolWitnessTable(inheritedProtocol);
3416-
if (conformance.isConcrete()) {
3411+
if (sourceKey.Kind.isConcreteProtocolConformance()) {
34173412
auto inheritedConformance =
3418-
conformance.getConcrete()->getInheritedConformance(inheritedProtocol);
3413+
sourceKey.Kind.getConcreteProtocolConformance()
3414+
->getInheritedConformance(inheritedProtocol);
34193415
if (inheritedConformance) {
34203416
sourceKey.Kind = LocalTypeDataKind::forConcreteProtocolWitnessTable(
34213417
inheritedConformance);
@@ -3438,8 +3434,8 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
34383434

34393435
case Component::Kind::AssociatedConformance: {
34403436
auto sourceType = sourceKey.Type;
3441-
auto sourceConformance = sourceKey.Kind.getProtocolConformance();
3442-
auto sourceProtocol = sourceConformance.getRequirement();
3437+
auto sourceConformance = sourceKey.Kind.getProtocolConformance(sourceType);
3438+
auto sourceProtocol = sourceKey.Kind.getConformedProtocol();
34433439
auto &pi = IGF.IGM.getProtocolInfo(sourceProtocol,
34443440
ProtocolInfoKind::RequirementSignature);
34453441

@@ -3473,7 +3469,8 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
34733469
// In Embedded Swift associated-conformance entries simply point to the witness table
34743470
// of the associated conformance.
34753471
llvm::Value *sourceWTable = source.getMetadata();
3476-
llvm::Value *associatedWTable = emitAssociatedConformanceValue(IGF, sourceWTable, associatedConformanceRef);
3472+
llvm::Value *associatedWTable = emitAssociatedConformanceValue(
3473+
IGF, sourceWTable, associatedConformanceRef);
34773474
return MetadataResponse::forComplete(associatedWTable);
34783475
}
34793476

@@ -3562,13 +3559,13 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
35623559
}
35633560

35643561
case Component::Kind::ConditionalConformance: {
3565-
auto sourceConformance = sourceKey.Kind.getProtocolConformance();
3562+
auto sourceConformance = sourceKey.Kind.getConcreteProtocolConformance();
35663563

35673564
auto reqtIndex = component.getPrimaryIndex();
35683565

35693566
ProtocolDecl *conformingProto;
35703567
auto found = SILWitnessTable::enumerateWitnessTableConditionalConformances(
3571-
sourceConformance.getConcrete(),
3568+
sourceConformance,
35723569
[&](unsigned index, CanType type, ProtocolDecl *proto) {
35733570
if (reqtIndex == index) {
35743571
conformingProto = proto;

lib/IRGen/LocalTypeDataKind.h

+16-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#ifndef SWIFT_IRGEN_LOCALTYPEDATAKIND_H
2020
#define SWIFT_IRGEN_LOCALTYPEDATAKIND_H
2121

22+
#include "swift/AST/PackConformance.h"
23+
#include "swift/AST/ProtocolConformance.h"
2224
#include "swift/AST/ProtocolConformanceRef.h"
2325
#include "swift/AST/Type.h"
2426
#include "swift/IRGen/ValueWitness.h"
@@ -183,13 +185,23 @@ class LocalTypeDataKind {
183185
return reinterpret_cast<PackConformance*>(Value - Kind_PackConformance);
184186
}
185187

186-
ProtocolConformanceRef getProtocolConformance() const {
188+
ProtocolDecl *getConformedProtocol() const {
189+
assert(!isSingletonKind());
190+
if ((Value & KindMask) == Kind_Decl) {
191+
return getAbstractProtocolConformance();
192+
} else if ((Value & KindMask) == Kind_PackConformance) {
193+
return getPackProtocolConformance()->getProtocol();
194+
} else {
195+
assert((Value & KindMask) == Kind_Conformance);
196+
return getConcreteProtocolConformance()->getProtocol();
197+
}
198+
}
199+
200+
ProtocolConformanceRef getProtocolConformance(Type conformingType) const {
187201
assert(!isSingletonKind());
188202
if ((Value & KindMask) == Kind_Decl) {
189-
// FIXME: Passing an empty Type() here temporarily while staging in
190-
// new representation for abstract conformances
191203
return ProtocolConformanceRef::forAbstract(
192-
Type(), getAbstractProtocolConformance());
204+
conformingType, getAbstractProtocolConformance());
193205
} else if ((Value & KindMask) == Kind_PackConformance) {
194206
return ProtocolConformanceRef(getPackProtocolConformance());
195207
} else {

0 commit comments

Comments
 (0)