Skip to content

Commit 47156e0

Browse files
committed
AST: Introduce ProtocolConformanceRef::forAbstract()
1 parent 8d05362 commit 47156e0

23 files changed

+100
-76
lines changed

include/swift/AST/ProtocolConformanceRef.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ class ProtocolConformanceRef {
5959

6060
explicit ProtocolConformanceRef(UnionType value) : Union(value) {}
6161

62-
public:
6362
/// Create an abstract protocol conformance reference.
6463
explicit ProtocolConformanceRef(ProtocolDecl *proto) : Union(proto) {
6564
assert(proto != nullptr &&
6665
"cannot construct ProtocolConformanceRef with null");
6766
}
6867

68+
public:
69+
ProtocolConformanceRef() : Union() {}
70+
6971
/// Create a concrete protocol conformance reference.
7072
explicit ProtocolConformanceRef(ProtocolConformance *conf) : Union(conf) {
7173
assert(conf != nullptr &&
@@ -78,9 +80,6 @@ class ProtocolConformanceRef {
7880
"cannot construct ProtocolConformanceRef with null");
7981
}
8082

81-
ProtocolConformanceRef(std::nullptr_t = nullptr)
82-
: Union((ProtocolDecl *)nullptr) {}
83-
8483
static ProtocolConformanceRef forInvalid() {
8584
return ProtocolConformanceRef();
8685
}
@@ -94,10 +93,9 @@ class ProtocolConformanceRef {
9493

9594
explicit operator bool() const { return !isInvalid(); }
9695

97-
/// Create either a concrete or an abstract protocol conformance reference,
98-
/// depending on whether ProtocolConformance is null.
99-
explicit ProtocolConformanceRef(ProtocolDecl *protocol,
100-
ProtocolConformance *conf);
96+
/// Create an abstract conformance for a type parameter or archetype.
97+
static ProtocolConformanceRef forAbstract(Type subjectType,
98+
ProtocolDecl *protocol);
10199

102100
bool isConcrete() const {
103101
return !isInvalid() && Union.is<ProtocolConformance*>();

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct SubstitutionMapWithLocalArchetypes {
9393
if (SubsMap)
9494
return SubsMap->lookupConformance(origType, proto);
9595

96-
return ProtocolConformanceRef(proto);
96+
return ProtocolConformanceRef::forAbstract(substType, proto);
9797
}
9898

9999
void dump(llvm::raw_ostream &out) const {

include/swift/Sema/ConstraintSystem.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,7 @@ class Solution {
16251625

16261626
/// The set of conformances synthesized during solving (i.e. for
16271627
/// ad-hoc distributed `SerializationRequirement` conformances).
1628-
llvm::DenseMap<ConstraintLocator *, ProtocolConformanceRef>
1628+
llvm::DenseMap<ConstraintLocator *, ProtocolDecl *>
16291629
SynthesizedConformances;
16301630

16311631
/// Record a new argument matching choice for given locator that maps a
@@ -2426,7 +2426,7 @@ class ConstraintSystem {
24262426

24272427
/// The set of conformances synthesized during solving (i.e. for
24282428
/// ad-hoc distributed `SerializationRequirement` conformances).
2429-
llvm::DenseMap<ConstraintLocator *, ProtocolConformanceRef>
2429+
llvm::DenseMap<ConstraintLocator *, ProtocolDecl *>
24302430
SynthesizedConformances;
24312431

24322432
private:
@@ -4948,7 +4948,7 @@ class ConstraintSystem {
49484948
TypeMatchOptions flags);
49494949

49504950
void recordSynthesizedConformance(ConstraintLocator *locator,
4951-
ProtocolConformanceRef conformance);
4951+
ProtocolDecl *conformance);
49524952

49534953
/// Attempt to simplify the given conformance constraint.
49544954
///

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,8 @@ SwiftDeclCollector::addConformancesToTypeDecl(SDKNodeDeclType *Root,
19761976
if (auto *PD = dyn_cast<ProtocolDecl>(NTD)) {
19771977
for (auto *inherited : PD->getAllInheritedProtocols()) {
19781978
if (!Ctx.shouldIgnore(inherited)) {
1979-
ProtocolConformanceRef Conf(inherited);
1979+
auto Conf = ProtocolConformanceRef::forAbstract(
1980+
PD->getSelfInterfaceType(), inherited);
19801981
auto ConfNode = SDKNodeInitInfo(Ctx, Conf)
19811982
.createSDKNode(SDKNodeKind::Conformance);
19821983
Root->addConformance(ConfNode);

lib/AST/ConformanceLookup.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ LookupConformanceInModuleRequest::evaluate(
509509

510510
for (auto ap : archetype->getConformsTo()) {
511511
if (ap == protocol || ap->inheritsFrom(protocol))
512-
return ProtocolConformanceRef(protocol);
512+
return ProtocolConformanceRef::forAbstract(archetype, protocol);
513513
}
514514

515515
return ProtocolConformanceRef::forMissingOrInvalid(type, protocol);
@@ -527,17 +527,17 @@ LookupConformanceInModuleRequest::evaluate(
527527

528528
// Type parameters have trivial conformances.
529529
if (type->isTypeParameter())
530-
return ProtocolConformanceRef(protocol);
530+
return ProtocolConformanceRef::forAbstract(type, protocol);
531531

532532
// Type variables have trivial conformances.
533533
if (type->isTypeVariableOrMember())
534-
return ProtocolConformanceRef(protocol);
534+
return ProtocolConformanceRef::forAbstract(type, protocol);
535535

536536
// UnresolvedType is a placeholder for an unknown type used when generating
537537
// diagnostics. We consider it to conform to all protocols, since the
538538
// intended type might have. Same goes for PlaceholderType.
539539
if (type->is<UnresolvedType>() || type->is<PlaceholderType>())
540-
return ProtocolConformanceRef(protocol);
540+
return ProtocolConformanceRef::forAbstract(type, protocol);
541541

542542
// Pack types can conform to protocols.
543543
if (auto packType = type->getAs<PackType>()) {

lib/AST/ExistentialGeneralization.cpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -195,35 +195,37 @@ class Generalizer : public CanTypeVisitor<Generalizer, Type> {
195195
newArgs.push_back(generalizeComponentType(CanType(origArg)));
196196
}
197197

198+
auto origSig = origSubs.getGenericSignature();
199+
198200
// Generalize all of the conformances.
199201
// TODO: for abstract requirements, we might not generalize all
200202
// arguments, and we may need to leave corresponding conformances
201203
// concrete.
202204
SmallVector<ProtocolConformanceRef, 4> newConformances;
203-
auto origConformances = origSubs.getConformances();
204-
for (auto origConformance: origConformances) {
205+
for (const auto &req : origSig.getRequirements()) {
206+
if (req.getKind() != RequirementKind::Conformance)
207+
continue;
205208
newConformances.push_back(
206-
ProtocolConformanceRef(origConformance.getRequirement()));
209+
ProtocolConformanceRef::forAbstract(req.getFirstType(),
210+
req.getProtocolDecl()));
207211
}
208212

209-
auto origSig = origSubs.getGenericSignature();
210213
auto newSubs = SubstitutionMap::get(origSig, newArgs, newConformances);
211214

212215
// Add any conformance requirements to the generic signature and
213216
// remember the conformances we generalized.
214-
if (!origConformances.empty()) {
215-
size_t i = 0;
216-
for (auto &origReq: origSig.getRequirements()) {
217-
if (origReq.getKind() != RequirementKind::Conformance) continue;
218-
auto origConformance = origConformances[i++];
219-
220-
auto newReq = origReq.subst(newSubs);
221-
addedRequirements.push_back(newReq);
222-
223-
substConformances.insert({{newReq.getFirstType()->getCanonicalType(),
224-
newReq.getProtocolDecl()},
225-
origConformance});
226-
}
217+
auto origConformances = origSubs.getConformances();
218+
size_t i = 0;
219+
for (auto &origReq: origSig.getRequirements()) {
220+
if (origReq.getKind() != RequirementKind::Conformance) continue;
221+
auto origConformance = origConformances[i++];
222+
223+
auto newReq = origReq.subst(newSubs);
224+
addedRequirements.push_back(newReq);
225+
226+
substConformances.insert({{newReq.getFirstType()->getCanonicalType(),
227+
newReq.getProtocolDecl()},
228+
origConformance});
227229
}
228230

229231
// Build the new type.

lib/AST/LocalArchetypeRequirementCollector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ swift::buildSubstitutionMapWithCapturedEnvironments(
265265
[&](CanType origType, Type substType,
266266
ProtocolDecl *proto) -> ProtocolConformanceRef {
267267
if (origType->getRootGenericParam()->getDepth() >= baseDepth)
268-
return ProtocolConformanceRef(proto);
268+
return ProtocolConformanceRef::forAbstract(substType, proto);
269269
return baseSubMap.lookupConformance(origType, proto);
270270
});
271271
}

lib/AST/ProtocolConformanceRef.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,10 @@
3333

3434
using namespace swift;
3535

36-
ProtocolConformanceRef::ProtocolConformanceRef(ProtocolDecl *protocol,
37-
ProtocolConformance *conf) {
38-
assert(protocol != nullptr &&
39-
"cannot construct ProtocolConformanceRef with null protocol");
40-
if (conf) {
41-
assert(protocol == conf->getProtocol() && "protocol conformance mismatch");
42-
Union = conf;
43-
} else {
44-
Union = protocol;
45-
}
36+
ProtocolConformanceRef ProtocolConformanceRef::forAbstract(
37+
Type subjectType, ProtocolDecl *proto) {
38+
// Temporary implementation:
39+
return ProtocolConformanceRef(proto);
4640
}
4741

4842
bool ProtocolConformanceRef::isInvalid() const {

lib/AST/SubstitutionMap.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ LookUpConformanceInOverrideSubs::operator()(CanType type,
491491
Type substType,
492492
ProtocolDecl *proto) const {
493493
if (type->getRootGenericParam()->getDepth() >= info.BaseDepth)
494-
return ProtocolConformanceRef(proto);
494+
return ProtocolConformanceRef::forAbstract(substType, proto);
495495

496496
if (auto conformance = info.BaseSubMap.lookupConformance(type, proto))
497497
return conformance;
@@ -696,7 +696,8 @@ ProtocolConformanceRef OuterSubstitutions::operator()(
696696
Type conformingReplacementType,
697697
ProtocolDecl *conformedProtocol) const {
698698
if (isUnsubstitutedTypeParameter(dependentType))
699-
return ProtocolConformanceRef(conformedProtocol);
699+
return ProtocolConformanceRef::forAbstract(
700+
conformingReplacementType, conformedProtocol);
700701

701702
return LookUpConformanceInSubstitutionMap(subs)(
702703
dependentType, conformingReplacementType, conformedProtocol);

lib/AST/TypeSubstitution.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ operator()(CanType dependentType, Type conformingReplacementType,
166166
return lookupConformance(archetypeType, conformedProtocol);
167167
}
168168
}
169-
return ProtocolConformanceRef(conformedProtocol);
169+
return ProtocolConformanceRef::forAbstract(
170+
conformingReplacementType, conformedProtocol);
170171
}
171172

172173
static Type substGenericFunctionType(GenericFunctionType *genericFnType,
@@ -1197,7 +1198,7 @@ ProtocolConformanceRef swift::substOpaqueTypesWithUnderlyingTypes(
11971198
ProtocolConformanceRef ReplaceOpaqueTypesWithUnderlyingTypes::
11981199
operator()(CanType maybeOpaqueType, Type replacementType,
11991200
ProtocolDecl *protocol) const {
1200-
auto abstractRef = ProtocolConformanceRef(protocol);
1201+
auto abstractRef = ProtocolConformanceRef::forAbstract(maybeOpaqueType, protocol);
12011202

12021203
auto archetype = dyn_cast<OpaqueTypeArchetypeType>(maybeOpaqueType);
12031204
if (!archetype) {

lib/IRGen/GenArchetype.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,10 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF,
306306
assert(rootWTable && "root witness table not bound in local context!");
307307
}
308308

309+
auto conformance = ProtocolConformanceRef::forAbstract(
310+
rootArchetype, rootProtocol);
309311
wtable = path.followFromWitnessTable(IGF, rootArchetype,
310-
ProtocolConformanceRef(rootProtocol),
312+
conformance,
311313
MetadataResponse::forComplete(rootWTable),
312314
/*request*/ MetadataState::Complete,
313315
nullptr).getMetadata();

lib/IRGen/GenPack.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,10 +354,12 @@ static void bindElementSignatureRequirementsAtIndex(
354354
patternPackArchetype)
355355
->getCanonicalType();
356356
llvm::Value *_metadata = nullptr;
357-
auto packConformance = ProtocolConformanceRef(proto);
357+
auto packConformance = ProtocolConformanceRef::forAbstract(
358+
patternPackArchetype, proto);
358359
auto *wtablePack = emitWitnessTableRef(IGF, patternPackArchetype,
359360
&_metadata, packConformance);
360-
auto elementConformance = ProtocolConformanceRef(proto);
361+
auto elementConformance = ProtocolConformanceRef::forAbstract(
362+
elementArchetype, proto);
361363
auto *wtable = bindWitnessTableAtIndex(
362364
IGF, elementArchetype, elementConformance, wtablePack, index);
363365
assert(wtable);

lib/IRGen/LocalTypeDataKind.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ class LocalTypeDataKind {
186186
ProtocolConformanceRef getProtocolConformance() const {
187187
assert(!isSingletonKind());
188188
if ((Value & KindMask) == Kind_Decl) {
189-
return ProtocolConformanceRef(getAbstractProtocolConformance());
189+
// FIXME: Passing an empty Type() here temporarily while staging in
190+
// new representation for abstract conformances
191+
return ProtocolConformanceRef::forAbstract(
192+
Type(), getAbstractProtocolConformance());
190193
} else if ((Value & KindMask) == Kind_PackConformance) {
191194
return ProtocolConformanceRef(getPackProtocolConformance());
192195
} else {

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3940,7 +3940,8 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant(
39403940

39413941
if (silRep == SILFunctionTypeRepresentation::WitnessMethod) {
39423942
auto proto = constant.getDecl()->getDeclContext()->getSelfProtocolDecl();
3943-
witnessMethodConformance = ProtocolConformanceRef(proto);
3943+
witnessMethodConformance = ProtocolConformanceRef::forAbstract(
3944+
proto->getSelfInterfaceType()->getCanonicalType(), proto);
39443945
}
39453946

39463947
// Does this constant have a preferred abstraction pattern set?

lib/SIL/IR/SILTypeSubstitution.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ class SILTypeSubstituter :
7575
Type conformingReplacementType,
7676
ProtocolDecl *conformedProtocol) -> ProtocolConformanceRef {
7777
return substOpaqueTypesWithUnderlyingTypes(
78-
ProtocolConformanceRef(conformedProtocol),
78+
ProtocolConformanceRef::forAbstract(conformingReplacementType,
79+
conformedProtocol),
7980
conformingReplacementType->getCanonicalType(),
8081
typeExpansionContext);
8182
},

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,7 +1875,8 @@ SubstitutionMap getApplySubstitutionsFromParsed(
18751875
proto->getDeclaredInterfaceType());
18761876
failed = true;
18771877

1878-
return ProtocolConformanceRef(proto);
1878+
// FIXME: Passing an empty Type() here temporarily.
1879+
return ProtocolConformanceRef::forAbstract(Type(), proto);
18791880
});
18801881

18811882
return failed ? SubstitutionMap() : subMap;
@@ -8162,7 +8163,8 @@ static bool parseSILWitnessTableEntry(
81628163
P.parseToken(tok::colon, diag::expected_sil_witness_colon))
81638164
return true;
81648165

8165-
ProtocolConformanceRef conformance(proto);
8166+
// FIXME: Passing an empty Type() here temporarily.
8167+
auto conformance = ProtocolConformanceRef::forAbstract(Type(), proto);
81668168
if (P.Tok.getText() != "dependent") {
81678169
auto concrete =
81688170
witnessState.parseProtocolConformance();

lib/SILGen/SILGenLValue.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,8 @@ namespace {
10881088

10891089
SmallVector<ProtocolConformanceRef, 2> conformances;
10901090
for (auto proto : OpenedArchetype->getConformsTo())
1091-
conformances.push_back(ProtocolConformanceRef(proto));
1091+
conformances.push_back(ProtocolConformanceRef::forAbstract(
1092+
OpenedArchetype, proto));
10921093

10931094
SILValue ref;
10941095
if (base.getType().is<ExistentialMetatypeType>()) {

lib/SILGen/SILGenType.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -915,11 +915,12 @@ static SILFunction *emitSelfConformanceWitness(SILGenModule &SGM,
915915
// Open the protocol type.
916916
auto openedType = OpenedArchetypeType::get(
917917
protocol->getDeclaredExistentialType()->getCanonicalType());
918+
auto openedConf = ProtocolConformanceRef::forAbstract(openedType, protocol);
918919

919920
// Form the substitutions for calling the witness.
920921
auto witnessSubs = SubstitutionMap::getProtocolSubstitutions(protocol,
921922
openedType,
922-
ProtocolConformanceRef(protocol));
923+
openedConf);
923924

924925
// Substitute to get the formal substituted type of the thunk.
925926
auto reqtSubstTy =
@@ -1073,8 +1074,11 @@ class SILGenDefaultWitnessTable
10731074
addMissingDefault();
10741075
return;
10751076
}
1077+
1078+
auto Conf = ProtocolConformanceRef::forAbstract(
1079+
Proto->getSelfInterfaceType()->getCanonicalType(), Proto);
10761080
SILFunction *witnessFn = SGM.emitProtocolWitness(
1077-
ProtocolConformanceRef(Proto), SILLinkage::Private, IsNotSerialized,
1081+
Conf, SILLinkage::Private, IsNotSerialized,
10781082
requirementRef, witnessRef, isFree, witness);
10791083
auto entry = SILWitnessTable::MethodWitness{requirementRef, witnessFn};
10801084
DefaultWitnesses.push_back(entry);

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
11811181
// base type of the existential's requirements.
11821182
return CEI.lookupExistentialConformance(proto);
11831183
}
1184-
return ProtocolConformanceRef(proto);
1184+
return ProtocolConformanceRef::forAbstract(substTy, proto);
11851185
}, SubstFlags::SubstituteLocalArchetypes);
11861186
continue;
11871187
}
@@ -1219,7 +1219,7 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
12191219
// base type of the existential's requirements.
12201220
return CEI.lookupExistentialConformance(proto);
12211221
}
1222-
return ProtocolConformanceRef(proto);
1222+
return ProtocolConformanceRef::forAbstract(substTy, proto);
12231223
}, SubstFlags::SubstituteLocalArchetypes);
12241224
}
12251225

0 commit comments

Comments
 (0)