ModuleInterface: Avoid attempting to print protocols inherited from superclasses.

"Extra" protocols from a superclass are already handled when printing the superclass, so we should not accumulate them when recording protocols for a subclass.

Resolves rdar://98523784
This commit is contained in:
Allan Shortlidge
2022-08-31 23:45:15 -07:00
parent 983e2f37d3
commit 145609248c
2 changed files with 29 additions and 6 deletions

View File

@@ -388,8 +388,12 @@ class InheritedProtocolCollector {
/// For each type in \p directlyInherited, classify the protocols it refers to
/// as included for printing or not, and record them in the appropriate
/// vectors.
///
/// If \p skipExtra is true then avoid recording any extra protocols to
/// print, such as synthesized conformances or conformances to non-public
/// protocols.
void recordProtocols(ArrayRef<InheritedEntry> directlyInherited,
const Decl *D, bool skipSynthesized = false) {
const Decl *D, bool skipExtra = false) {
Optional<AvailableAttrList> availableAttrs;
for (InheritedEntry inherited : directlyInherited) {
@@ -398,6 +402,9 @@ class InheritedProtocolCollector {
continue;
bool canPrintNormally = canPrintProtocolTypeNormally(inheritedTy, D);
if (!canPrintNormally && skipExtra)
continue;
ExistentialLayout layout = inheritedTy->getExistentialLayout();
for (ProtocolDecl *protoDecl : layout.getProtocols()) {
if (canPrintNormally)
@@ -411,7 +418,7 @@ class InheritedProtocolCollector {
// any of those besides 'AnyObject'.
}
if (skipSynthesized)
if (skipExtra)
return;
// Check for synthesized protocols, like Hashable on enums.
@@ -493,11 +500,12 @@ public:
if (auto *CD = dyn_cast<ClassDecl>(D)) {
for (auto *SD = CD->getSuperclassDecl(); SD;
SD = SD->getSuperclassDecl()) {
map[nominal].recordProtocols(
SD->getInherited(), SD, /*skipSynthesized=*/true);
map[nominal].recordProtocols(SD->getInherited(), SD,
/*skipExtra=*/true);
for (auto *Ext: SD->getExtensions()) {
if (shouldInclude(Ext)) {
map[nominal].recordProtocols(Ext->getInherited(), Ext);
map[nominal].recordProtocols(Ext->getInherited(), Ext,
/*skipExtra=*/true);
}
}
}