Skip to content

Commit cb845d8

Browse files
committed
AST: Fix protocol composition canonicalization for primitive AnyObject
We were neglecting to take a primitive AnyObject member into account. Also, canonicalize 'SomeClass & SomeProto & AnyObject' down to 'SomeClass & SomeProto'.
1 parent 3b333ff commit cb845d8

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

lib/AST/Type.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -889,16 +889,20 @@ Type TypeBase::getRValueInstanceType() {
889889

890890
/// \brief Collect the protocols in the existential type T into the given
891891
/// vector.
892-
static void addProtocols(Type T, SmallVectorImpl<ProtocolDecl *> &Protocols,
893-
Type &Superclass) {
892+
static void addProtocols(Type T,
893+
SmallVectorImpl<ProtocolDecl *> &Protocols,
894+
Type &Superclass,
895+
bool &HasExplicitAnyObject) {
894896
if (auto Proto = T->getAs<ProtocolType>()) {
895897
Protocols.push_back(Proto->getDecl());
896898
return;
897899
}
898900

899901
if (auto PC = T->getAs<ProtocolCompositionType>()) {
902+
if (PC->hasExplicitAnyObject())
903+
HasExplicitAnyObject = true;
900904
for (auto P : PC->getMembers())
901-
addProtocols(P, Protocols, Superclass);
905+
addProtocols(P, Protocols, Superclass, HasExplicitAnyObject);
902906
return;
903907
}
904908

@@ -2780,12 +2784,16 @@ Type ProtocolCompositionType::get(const ASTContext &C,
27802784
Type Superclass;
27812785
SmallVector<ProtocolDecl *, 4> Protocols;
27822786
for (Type t : Members) {
2783-
addProtocols(t, Protocols, Superclass);
2787+
addProtocols(t, Protocols, Superclass, HasExplicitAnyObject);
27842788
}
27852789

27862790
// Minimize the set of protocols composed together.
27872791
ProtocolType::canonicalizeProtocols(Protocols);
27882792

2793+
// The presence of a superclass constraint makes AnyObject redundant.
2794+
if (Superclass)
2795+
HasExplicitAnyObject = false;
2796+
27892797
// If one protocol remains with no further constraints, its nominal
27902798
// type is the canonical type.
27912799
if (Protocols.size() == 1 && !Superclass && !HasExplicitAnyObject)
@@ -2803,8 +2811,7 @@ Type ProtocolCompositionType::get(const ASTContext &C,
28032811
});
28042812

28052813
// TODO: Canonicalize away HasExplicitAnyObject if it is implied
2806-
// by one of our member protocols or the presence of a superclass
2807-
// constraint.
2814+
// by one of our member protocols.
28082815
return build(C, CanTypes, HasExplicitAnyObject);
28092816
}
28102817

0 commit comments

Comments
 (0)