Skip to content

Commit 12a942b

Browse files
authored
Merge pull request #77664 from slavapestov/abstract-conformance-prep
AST: Introduce ProtocolConformanceRef::forAbstract()
2 parents 03dc0af + 47156e0 commit 12a942b

26 files changed

+110
-110
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/DistributedDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ swift::getDistributedActorAsActorConformanceRef(ASTContext &C) {
130130
auto distributedActorAsActorConformance =
131131
getDistributedActorAsActorConformance(C);
132132

133-
auto actorProto = C.getProtocol(KnownProtocolKind::Actor);
134-
return ProtocolConformanceRef(actorProto, distributedActorAsActorConformance);
133+
return ProtocolConformanceRef(distributedActorAsActorConformance);
135134
}
136135
NormalProtocolConformance *
137136
swift::getDistributedActorAsActorConformance(ASTContext &C) {

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: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,8 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const {
271271

272272
// If the protocol is invertible, fall back to a global lookup instead of
273273
// evaluating a conformance path, to avoid an infinite substitution issue.
274-
if (proto->getInvertibleProtocolKind()) {
275-
auto substType = type.subst(*this);
276-
if (!substType->isTypeParameter())
277-
return swift::lookupConformance(substType, proto);
278-
return ProtocolConformanceRef(proto);
279-
}
274+
if (proto->getInvertibleProtocolKind())
275+
return swift::lookupConformance(type.subst(*this), proto);
280276

281277
auto path = genericSig->getConformancePath(type, proto);
282278

@@ -300,18 +296,7 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const {
300296
if (conformance.isAbstract()) {
301297
// FIXME: Rip this out once we can get a concrete conformance from
302298
// an archetype.
303-
auto substType = type.subst(*this);
304-
if (substType->hasError())
305-
return ProtocolConformanceRef(proto);
306-
307-
if ((!substType->is<ArchetypeType>() ||
308-
substType->castTo<ArchetypeType>()->getSuperclass()) &&
309-
!substType->isTypeParameter() &&
310-
!substType->isExistentialType()) {
311-
return swift::lookupConformance(substType, proto);
312-
}
313-
314-
return ProtocolConformanceRef(proto);
299+
return swift::lookupConformance(type.subst(*this), proto);
315300
}
316301

317302
// For the second step, we're looking into the requirement signature for
@@ -506,14 +491,11 @@ LookUpConformanceInOverrideSubs::operator()(CanType type,
506491
Type substType,
507492
ProtocolDecl *proto) const {
508493
if (type->getRootGenericParam()->getDepth() >= info.BaseDepth)
509-
return ProtocolConformanceRef(proto);
494+
return ProtocolConformanceRef::forAbstract(substType, proto);
510495

511496
if (auto conformance = info.BaseSubMap.lookupConformance(type, proto))
512497
return conformance;
513498

514-
if (substType->isTypeParameter())
515-
return ProtocolConformanceRef(proto);
516-
517499
return lookupConformance(substType, proto);
518500
}
519501

@@ -714,7 +696,8 @@ ProtocolConformanceRef OuterSubstitutions::operator()(
714696
Type conformingReplacementType,
715697
ProtocolDecl *conformedProtocol) const {
716698
if (isUnsubstitutedTypeParameter(dependentType))
717-
return ProtocolConformanceRef(conformedProtocol);
699+
return ProtocolConformanceRef::forAbstract(
700+
conformingReplacementType, conformedProtocol);
718701

719702
return LookUpConformanceInSubstitutionMap(subs)(
720703
dependentType, conformingReplacementType, conformedProtocol);

lib/AST/Type.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,15 +2306,11 @@ class IsBindableVisitor : public TypeVisitor<IsBindableVisitor, CanType, CanType
23062306
QueryTypeSubstitutionMap{newParamsMap},
23072307
LookUpConformanceInModule());
23082308

2309-
if (newSubstTy->isTypeParameter()) {
2310-
newConformances.push_back(ProtocolConformanceRef(proto));
2311-
} else {
2312-
auto newConformance
2313-
= lookupConformance(newSubstTy, proto, /*allowMissing=*/true);
2314-
if (!newConformance)
2315-
return CanType();
2316-
newConformances.push_back(newConformance);
2317-
}
2309+
auto newConformance
2310+
= lookupConformance(newSubstTy, proto, /*allowMissing=*/true);
2311+
if (!newConformance)
2312+
return CanType();
2313+
newConformances.push_back(newConformance);
23182314
}
23192315
}
23202316

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();

0 commit comments

Comments
 (0)