Skip to content

Commit 5fba4b3

Browse files
authored
Merge pull request swiftlang#30484 from nkcsgexi/58563540
ModuleInterface: consider inherited protocols from super class when collecting handled protocols
2 parents 897d211 + 45d0eca commit 5fba4b3

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,21 +294,26 @@ class InheritedProtocolCollector {
294294
const NominalTypeDecl *nominal;
295295
const IterableDeclContext *memberContext;
296296

297+
auto shouldInclude = [](const ExtensionDecl *extension) {
298+
if (extension->isConstrainedExtension()) {
299+
// Conditional conformances never apply to inherited protocols, nor
300+
// can they provide unconditional conformances that might be used in
301+
// other extensions.
302+
return false;
303+
}
304+
return true;
305+
};
297306
if ((nominal = dyn_cast<NominalTypeDecl>(D))) {
298307
directlyInherited = nominal->getInherited();
299308
memberContext = nominal;
300309

301310
} else if (auto *extension = dyn_cast<ExtensionDecl>(D)) {
302-
if (extension->isConstrainedExtension()) {
303-
// Conditional conformances never apply to inherited protocols, nor
304-
// can they provide unconditional conformances that might be used in
305-
// other extensions.
311+
if (!shouldInclude(extension)) {
306312
return;
307313
}
308314
nominal = extension->getExtendedNominal();
309315
directlyInherited = extension->getInherited();
310316
memberContext = extension;
311-
312317
} else {
313318
return;
314319
}
@@ -317,6 +322,18 @@ class InheritedProtocolCollector {
317322
return;
318323

319324
map[nominal].recordProtocols(directlyInherited, D);
325+
// Collect protocols inherited from super classes
326+
if (auto *CD = dyn_cast<ClassDecl>(D)) {
327+
for (auto *SD = CD->getSuperclassDecl(); SD;
328+
SD = SD->getSuperclassDecl()) {
329+
map[nominal].recordProtocols(SD->getInherited(), SD);
330+
for (auto *Ext: SD->getExtensions()) {
331+
if (shouldInclude(Ext)) {
332+
map[nominal].recordProtocols(Ext->getInherited(), Ext);
333+
}
334+
}
335+
}
336+
}
320337

321338
// Recurse to find any nested types.
322339
for (const Decl *member : memberContext->getMembers())
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -typecheck -module-name Foo -emit-module-interface-path %t/Foo.swiftinterface %s
3+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Foo.swiftinterface -o %t/Foo.swiftmodule
4+
5+
public protocol ProtocolA : class {}
6+
public protocol ProtocolB: ProtocolA {}
7+
protocol ProtocolC: ProtocolA {}
8+
9+
public class A: ProtocolB {}
10+
public class B: A, ProtocolC {}

0 commit comments

Comments
 (0)