Skip to content

Commit 007fe96

Browse files
committed
AST: Don't build useless inherited conformances
1 parent 3b03a5e commit 007fe96

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

include/swift/AST/ASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ class ASTContext final {
12551255
/// \param type The type for which we are retrieving the conformance.
12561256
///
12571257
/// \param inherited The inherited conformance.
1258-
InheritedProtocolConformance *
1258+
ProtocolConformance *
12591259
getInheritedConformance(Type type, ProtocolConformance *inherited);
12601260

12611261
/// Get the lazy data for the given declaration.

lib/AST/ASTContext.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,30 +2448,39 @@ ASTContext::getSpecializedConformance(Type type,
24482448
return result;
24492449
}
24502450

2451-
InheritedProtocolConformance *
2451+
ProtocolConformance *
24522452
ASTContext::getInheritedConformance(Type type, ProtocolConformance *inherited) {
24532453
// Collapse multiple levels of inherited conformance.
2454-
while (auto *otherInherited = dyn_cast<InheritedProtocolConformance>(inherited))
2454+
if (auto *otherInherited = dyn_cast<InheritedProtocolConformance>(inherited))
24552455
inherited = otherInherited->getInheritedConformance();
24562456

24572457
assert(isa<SpecializedProtocolConformance>(inherited) ||
24582458
isa<NormalProtocolConformance>(inherited) ||
24592459
isa<BuiltinProtocolConformance>(inherited));
24602460

2461+
// Collapse useless inherited conformances. Conformance lookup with aa
2462+
// archetype T that has a superclass bound C will return a concrete
2463+
// conformance if C conforms to the protocol P. This is wrapped in an
2464+
// inherited conformance with the archetype type T. If you then substitute
2465+
// T := C, you don't want to form an inherited conformance with a type of
2466+
// C, because the underlying conformance already has a type of C.
2467+
if (inherited->getType()->isEqual(type))
2468+
return inherited;
2469+
24612470
llvm::FoldingSetNodeID id;
24622471
InheritedProtocolConformance::Profile(id, type, inherited);
24632472

24642473
// Figure out which arena this conformance should go into.
24652474
AllocationArena arena = getArena(type->getRecursiveProperties());
24662475

2467-
// Did we already record the normal protocol conformance?
2476+
// Did we already record the inherited protocol conformance?
24682477
void *insertPos;
24692478
auto &inheritedConformances = getImpl().getArena(arena).InheritedConformances;
24702479
if (auto result
24712480
= inheritedConformances.FindNodeOrInsertPos(id, insertPos))
24722481
return result;
24732482

2474-
// Build a new normal protocol conformance.
2483+
// Build a new inherited protocol conformance.
24752484
auto result = new (*this, arena) InheritedProtocolConformance(type, inherited);
24762485
inheritedConformances.InsertNode(result, insertPos);
24772486
return result;

0 commit comments

Comments
 (0)