Skip to content

Commit 2c3aa5d

Browse files
authored
Merge pull request #74838 from tshortli/nested-function-exportability
AST: Functions nested in exportable functions are also exportable
2 parents 3a3c92b + d48f949 commit 2c3aa5d

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

include/swift/AST/DeclExportabilityVisitor.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@ class DeclExportabilityVisitor
5050
bool visitDecl(const Decl *D) = delete;
5151
bool visitValueDecl(const ValueDecl *valueDecl) = delete;
5252

53+
bool visitAbstractFunctionDecl(const AbstractFunctionDecl *afd) {
54+
// If this function is nested within another function that is exportable to
55+
// clients then it is also exportable.
56+
auto dc = afd->getDeclContext();
57+
do {
58+
if (auto parent = dyn_cast<AbstractFunctionDecl>(dc)) {
59+
if (DeclExportabilityVisitor().visit(parent))
60+
return true;
61+
}
62+
} while ((dc = dc->getParent()));
63+
64+
return false;
65+
}
66+
5367
bool visitExtensionDecl(const ExtensionDecl *ext) {
5468
// Extensions must extend exportable types to be exportable.
5569
auto nominalType = ext->getExtendedNominal();
@@ -135,7 +149,6 @@ class DeclExportabilityVisitor
135149
DEFAULT_TO_ACCESS_LEVEL(TypeAlias);
136150
DEFAULT_TO_ACCESS_LEVEL(AssociatedType);
137151
DEFAULT_TO_ACCESS_LEVEL(AbstractStorage);
138-
DEFAULT_TO_ACCESS_LEVEL(AbstractFunction);
139152
DEFAULT_TO_ACCESS_LEVEL(Macro);
140153
DEFAULT_TO_ACCESS_LEVEL(EnumElement);
141154

lib/SILGen/SILGen.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -805,20 +805,6 @@ bool SILGenModule::shouldSkipDecl(Decl *D) {
805805
if (D->isExposedToClients())
806806
return false;
807807

808-
if (isa<AbstractFunctionDecl>(D)) {
809-
// If this function is nested within another function that is exposed to
810-
// clients then it should be emitted.
811-
auto dc = D->getDeclContext();
812-
do {
813-
if (auto afd = dyn_cast<AbstractFunctionDecl>(dc))
814-
if (afd->isExposedToClients())
815-
return false;
816-
} while ((dc = dc->getParent()));
817-
818-
// We didn't find a parent function that is exposed.
819-
return true;
820-
}
821-
822808
return true;
823809
}
824810

test/Serialization/Safety/unsafe-decls.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,20 @@ public struct PublicStruct {
7070
// SAFETY-PRIVATE: Serialization safety, unsafe: 'init(fileprivateInit:)'
7171

7272
@inlinable public func inlinableFunc() {
73+
// SAFETY-PRIVATE: Serialization safety, safe: 'inlinableFunc()'
7374
typealias localTypealias = Int
75+
76+
func inlinableFunc_nested() {}
77+
// SAFETY-PRIVATE-NOT: inlinableFunc_nested()
78+
inlinableFunc_nested()
7479
}
75-
// SAFETY-PRIVATE: Serialization safety, safe: 'inlinableFunc()'
76-
public func publicFunc() {}
80+
81+
public func publicFunc() {
7782
// SAFETY-PRIVATE: Serialization safety, safe: 'publicFunc()'
83+
func publicFunc_nested() {}
84+
// SAFETY-PRIVATE-NOT: publicFunc_nested()
85+
publicFunc_nested()
86+
}
7887

7988
@available(SwiftStdlib 5.1, *) // for the `some` keyword.
8089
public func opaqueTypeFunc() -> some PublicProto {

0 commit comments

Comments
 (0)