mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
ModuleInterface: consider inherited protocols from super class when collecting handled protocols
Protocol conformances can be implied by super classes. When collecting the list of IncludedProtocols, we should traverse the class inheritance chain and collect all protocols. Without this change, these implied conformances will be printed again via a synthesized extension at the end of the Swift interface file, leading to an error of redundant conformances when building modules. rdar://58563540
This commit is contained in:
@@ -294,21 +294,26 @@ public:
|
||||
const NominalTypeDecl *nominal;
|
||||
const IterableDeclContext *memberContext;
|
||||
|
||||
auto shouldInclude = [](const ExtensionDecl *extension) {
|
||||
if (extension->isConstrainedExtension()) {
|
||||
// Conditional conformances never apply to inherited protocols, nor
|
||||
// can they provide unconditional conformances that might be used in
|
||||
// other extensions.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if ((nominal = dyn_cast<NominalTypeDecl>(D))) {
|
||||
directlyInherited = nominal->getInherited();
|
||||
memberContext = nominal;
|
||||
|
||||
} else if (auto *extension = dyn_cast<ExtensionDecl>(D)) {
|
||||
if (extension->isConstrainedExtension()) {
|
||||
// Conditional conformances never apply to inherited protocols, nor
|
||||
// can they provide unconditional conformances that might be used in
|
||||
// other extensions.
|
||||
if (!shouldInclude(extension)) {
|
||||
return;
|
||||
}
|
||||
nominal = extension->getExtendedNominal();
|
||||
directlyInherited = extension->getInherited();
|
||||
memberContext = extension;
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -317,6 +322,18 @@ public:
|
||||
return;
|
||||
|
||||
map[nominal].recordProtocols(directlyInherited, D);
|
||||
// Collect protocols inherited from super classes
|
||||
if (auto *CD = dyn_cast<ClassDecl>(D)) {
|
||||
for (auto *SD = CD->getSuperclassDecl(); SD;
|
||||
SD = SD->getSuperclassDecl()) {
|
||||
map[nominal].recordProtocols(SD->getInherited(), SD);
|
||||
for (auto *Ext: SD->getExtensions()) {
|
||||
if (shouldInclude(Ext)) {
|
||||
map[nominal].recordProtocols(Ext->getInherited(), Ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse to find any nested types.
|
||||
for (const Decl *member : memberContext->getMembers())
|
||||
|
||||
Reference in New Issue
Block a user