Skip to content

Commit ad417c9

Browse files
committed
AST: Update ProtocolCompositionType::requiresClass() for subclass existentials
Whether a protocol composition requires a class is no longer solely a property of what protocols it contains; now, a protocol composition consisting of a non-class constrained protocol and a superclass should return true from requiresClass(). This is done by looking at the ExistentialLayout, instead of walking the members directly.
1 parent 32a7505 commit ad417c9

File tree

3 files changed

+13
-22
lines changed

3 files changed

+13
-22
lines changed

include/swift/AST/Types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,7 +3605,7 @@ class ProtocolType : public NominalType, public llvm::FoldingSetNode {
36053605
}
36063606

36073607
/// True if only classes may conform to the protocol.
3608-
bool requiresClass() const;
3608+
bool requiresClass();
36093609

36103610
// Implement isa/cast/dyncast/etc.
36113611
static bool classof(const TypeBase *T) {
@@ -3678,7 +3678,7 @@ class ProtocolCompositionType : public TypeBase, public llvm::FoldingSetNode {
36783678
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef<Type> Protocols);
36793679

36803680
/// True if one or more of the protocols is class.
3681-
bool requiresClass() const;
3681+
bool requiresClass();
36823682

36833683
// Implement isa/cast/dyncast/etc.
36843684
static bool classof(const TypeBase *T) {

lib/AST/Decl.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2727,16 +2727,16 @@ ProtocolDecl::getInheritedProtocols() const {
27272727
// FIXME: Gather inherited protocols from the "inherited" list.
27282728
// We shouldn't need this, but it shows up in recursive invocations.
27292729
if (!isRequirementSignatureComputed()) {
2730+
SmallPtrSet<ProtocolDecl *, 4> known;
27302731
for (auto inherited : getInherited()) {
2731-
SmallPtrSet<ProtocolDecl *, 4> known;
27322732
if (auto type = inherited.getType()) {
2733-
if (type->isExistentialType()) {
2734-
SmallVector<ProtocolDecl *, 4> protocols;
2735-
type->getExistentialTypeProtocols(protocols);
2736-
for (auto proto : protocols) {
2737-
if (known.insert(proto).second)
2738-
result.push_back(proto);
2739-
}
2733+
// Only protocols can appear in the inheritance clause
2734+
// of a protocol -- anything else should get diagnosed
2735+
// elsewhere.
2736+
if (auto *protoTy = type->getAs<ProtocolType>()) {
2737+
auto *protoDecl = protoTy->getDecl();
2738+
if (known.insert(protoDecl).second)
2739+
result.push_back(protoDecl);
27402740
}
27412741
}
27422742
}

lib/AST/Type.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2744,21 +2744,12 @@ void ProtocolCompositionType::Profile(llvm::FoldingSetNodeID &ID,
27442744
ID.AddPointer(P.getPointer());
27452745
}
27462746

2747-
bool ProtocolType::requiresClass() const {
2747+
bool ProtocolType::requiresClass() {
27482748
return getDecl()->requiresClass();
27492749
}
27502750

2751-
bool ProtocolCompositionType::requiresClass() const {
2752-
for (Type t : getProtocols()) {
2753-
if (const ProtocolType *proto = t->getAs<ProtocolType>()) {
2754-
if (proto->requiresClass())
2755-
return true;
2756-
} else {
2757-
if (t->castTo<ProtocolCompositionType>()->requiresClass())
2758-
return true;
2759-
}
2760-
}
2761-
return false;
2751+
bool ProtocolCompositionType::requiresClass() {
2752+
return getExistentialLayout().requiresClass;
27622753
}
27632754

27642755
Type ProtocolCompositionType::get(const ASTContext &C,

0 commit comments

Comments
 (0)