Skip to content

Commit b56c143

Browse files
committed
Sema: Loosen exportability checking for non-publicly imported types
This one is specific. Allow extensions to define public members to package types implicitly exporting their memory layout when imported non-publicly. Enabling exportability checks for non-library-evolution by default as a warning triggered marking such types as implicitly exported to clients. This in turn enabled erroring on the extensions in clients when imported non-publicly. This error would be source breaking and shouldn't be required in such a context. We may even consider lifting this restriction entierly, even for public types imported non-public.
1 parent 810611d commit b56c143

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

lib/AST/Availability.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,5 +1062,5 @@ ExportedLevel swift::isExported(const ExtensionDecl *ED) {
10621062
for (const Decl *D : ED->getMembers())
10631063
membersExported = std::max(membersExported, isExported(D));
10641064

1065-
return membersExported;
1065+
return std::min(exported, membersExported);
10661066
}

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,12 @@ static bool shouldDiagnoseDeclAccess(const ValueDecl *D,
252252
switch (*reason) {
253253
case ExportabilityReason::ExtensionWithPublicMembers:
254254
case ExportabilityReason::ExtensionWithConditionalConformances:
255-
return true;
255+
// Allow public members in extensions of implicitly exported types.
256+
// Extensions cannot define stored variables avoiding the memory layout
257+
// concerns and we don't print swiftinterfaces in non-library-evolution
258+
// mode.
259+
// We may want to allow to simply return false and always allow this.
260+
return where.getExportedLevel() == ExportedLevel::Exported;
256261
case ExportabilityReason::Inheritance:
257262
case ExportabilityReason::ImplicitlyPublicInheritance:
258263
return isa<ProtocolDecl>(D);

test/Sema/access-level-import-classic-exportability.swift

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,52 @@
11
// RUN: %empty-directory(%t)
22
// RUN: split-file --leading-lines %s %t
33

4-
/// Build the libraries.
4+
/// Non-library-evolution.
5+
// RUN: %target-swift-frontend -emit-module %t/PublicLib.swift -o %t
6+
// RUN: %target-swift-frontend -emit-module %t/PackageLib.swift -o %t
7+
// RUN: %target-swift-frontend -emit-module %t/InternalLib.swift -o %t \
8+
// RUN: -package-name pkg
9+
// RUN: %target-swift-frontend -emit-module %t/FileprivateLib.swift -o %t
10+
// RUN: %target-swift-frontend -emit-module %t/PrivateLib.swift -o %t
11+
12+
/// Check diagnostics.
13+
// RUN: %target-swift-frontend -typecheck %t/Client.swift -I %t \
14+
// RUN: -package-name pkg -swift-version 5 \
15+
// RUN: -verify -verify-ignore-unrelated
16+
17+
/// CheckImplementationOnly doesn't change the results.
18+
// RUN: %target-swift-frontend -typecheck %t/Client.swift -I %t \
19+
// RUN: -package-name pkg -swift-version 5 \
20+
// RUN: -enable-experimental-feature CheckImplementationOnly \
21+
// RUN: -verify -verify-ignore-unrelated
22+
23+
24+
/// Library-evolution.
525
// RUN: %target-swift-frontend -emit-module %t/PublicLib.swift -o %t \
626
// RUN: -enable-library-evolution
727
// RUN: %target-swift-frontend -emit-module %t/PackageLib.swift -o %t \
828
// RUN: -enable-library-evolution
929
// RUN: %target-swift-frontend -emit-module %t/InternalLib.swift -o %t \
10-
// RUN: -enable-library-evolution
30+
// RUN: -enable-library-evolution -package-name pkg
1131
// RUN: %target-swift-frontend -emit-module %t/FileprivateLib.swift -o %t \
1232
// RUN: -enable-library-evolution
1333
// RUN: %target-swift-frontend -emit-module %t/PrivateLib.swift -o %t \
1434
// RUN: -enable-library-evolution
1535

1636
/// Check diagnostics.
1737
// RUN: %target-swift-frontend -typecheck %t/Client.swift -I %t \
18-
// RUN: -package-name TestPackage -swift-version 5 \
19-
// RUN: -enable-experimental-feature AccessLevelOnImport -verify -verify-ignore-unrelated
38+
// RUN: -package-name pkg -swift-version 5 \
39+
// RUN: -enable-library-evolution \
40+
// RUN: -verify -verify-ignore-unrelated
2041

21-
/// Check diagnostics with library-evolution.
42+
/// CheckImplementationOnly doesn't change the results.
2243
// RUN: %target-swift-frontend -typecheck %t/Client.swift -I %t \
23-
// RUN: -package-name TestPackage -swift-version 5 \
44+
// RUN: -package-name pkg -swift-version 5 \
2445
// RUN: -enable-library-evolution \
25-
// RUN: -enable-experimental-feature AccessLevelOnImport -verify -verify-ignore-unrelated
46+
// RUN: -enable-experimental-feature CheckImplementationOnly \
47+
// RUN: -verify -verify-ignore-unrelated
2648

27-
// REQUIRES: swift_feature_AccessLevelOnImport
49+
// REQUIRES: swift_feature_CheckImplementationOnly
2850

2951
//--- PublicLib.swift
3052
public struct PublicImportType {
@@ -41,6 +63,8 @@ public struct InternalImportType {
4163
public init() {}
4264
}
4365

66+
package struct InternalImportPackageType {}
67+
4468
//--- FileprivateLib.swift
4569
public struct FileprivateImportType {
4670
public init() {}
@@ -141,6 +165,9 @@ extension Array: InternalConstrainedExtensionProtoInFileprivate where Element ==
141165
extension InternalImportType {
142166
fileprivate func fileprivateMethod() {}
143167
}
168+
extension InternalImportPackageType { // No error
169+
public func foo() {}
170+
}
144171

145172
private protocol InternalConstrainedExtensionProtoInPrivate {}
146173
extension Array: InternalConstrainedExtensionProtoInPrivate where Element == InternalImportType {}

0 commit comments

Comments
 (0)