Skip to content

Commit 17b8e86

Browse files
committed
Sema: Support newer import restrictions with cross-import overlays
Add support for access-level on imports and `@_spiOnly imports` to cross import overlays. The overlay inherits the most restrictive import access-level of the declaring module and the bystander module. rdar://129606112
1 parent f53be71 commit 17b8e86

File tree

5 files changed

+239
-6
lines changed

5 files changed

+239
-6
lines changed

lib/Sema/ImportResolution.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,13 @@ UnboundImport::UnboundImport(
13541354
if (declaringOptions.contains(ImportFlags::ImplementationOnly) ||
13551355
bystandingOptions.contains(ImportFlags::ImplementationOnly))
13561356
import.options |= ImportFlags::ImplementationOnly;
1357+
if (declaringOptions.contains(ImportFlags::SPIOnly) ||
1358+
bystandingOptions.contains(ImportFlags::SPIOnly))
1359+
import.options |= ImportFlags::SPIOnly;
1360+
1361+
// Pick the most restrictive access level.
1362+
import.accessLevel = std::min(declaringImport.accessLevel,
1363+
bystandingImport.accessLevel);
13571364

13581365
// If either have a `@_documentation(visibility: <access>)` attribute, the
13591366
// cross-import has the more restrictive of the two.

lib/Sema/TypeCheckAccess.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,13 @@ static void noteLimitingImport(const Decl *userDecl,
404404
limitImport->accessLevel,
405405
limitImport->module.importedModule);
406406

407-
ctx.Diags.diagnose(limitImport->importLoc,
408-
diag::decl_import_via_here,
409-
VD,
410-
limitImport->accessLevel,
411-
limitImport->module.importedModule);
412-
} else {
407+
if (limitImport->importLoc.isValid())
408+
ctx.Diags.diagnose(limitImport->importLoc,
409+
diag::decl_import_via_here,
410+
VD,
411+
limitImport->accessLevel,
412+
limitImport->module.importedModule);
413+
} else if (limitImport->importLoc.isValid()) {
413414
ctx.Diags.diagnose(limitImport->importLoc, diag::module_imported_here,
414415
limitImport->module.importedModule,
415416
limitImport->accessLevel);
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/// Check semantic verification cross-import overlays with non-public imports.
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: cp -r %S/Inputs/lib-templates/* %t/
5+
// RUN: split-file --leading-lines %s %t
6+
7+
//--- BothPublic.swift
8+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/BothPublic.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
9+
10+
public import DeclaringLibrary
11+
public import BystandingLibrary
12+
13+
public func fn(_: OverlayLibraryTy) {}
14+
15+
16+
//--- BothHidden.swift
17+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/BothHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -verify
18+
19+
internal import DeclaringLibrary
20+
internal import BystandingLibrary
21+
22+
public func fn(_: OverlayLibraryTy) {}
23+
// expected-error @-1 {{function cannot be declared public because its parameter uses an internal type}}
24+
// expected-note @-2 {{struct 'OverlayLibraryTy' is imported by this file as 'internal' from '_OverlayLibrary'}}
25+
26+
27+
//--- FirstHidden.swift
28+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/FirstHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -verify
29+
30+
internal import DeclaringLibrary
31+
public import BystandingLibrary // expected-warning {{public import of 'BystandingLibrary' was not used in public declarations or inlinable code}}
32+
33+
public func fn(_: OverlayLibraryTy) {}
34+
// expected-error @-1 {{function cannot be declared public because its parameter uses an internal type}}
35+
// expected-note @-2 {{struct 'OverlayLibraryTy' is imported by this file as 'internal' from '_OverlayLibrary'}}
36+
37+
38+
//--- SecondHidden.swift
39+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/SecondHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -verify
40+
41+
public import DeclaringLibrary // expected-warning {{public import of 'DeclaringLibrary' was not used in public declarations or inlinable code}}
42+
internal import BystandingLibrary
43+
44+
public func fn(_: OverlayLibraryTy) {}
45+
// expected-error @-1 {{function cannot be declared public because its parameter uses an internal type}}
46+
// expected-note @-2 {{struct 'OverlayLibraryTy' is imported by this file as 'internal' from '_OverlayLibrary'}}
47+
48+
49+
//--- PrivateVsInternal.swift
50+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/PrivateVsInternal.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -verify
51+
52+
private import DeclaringLibrary
53+
internal import BystandingLibrary
54+
55+
internal func fn(_: OverlayLibraryTy) {}
56+
// expected-error @-1 {{function cannot be declared internal because its parameter uses a private type}}
57+
// expected-note @-2 {{struct 'OverlayLibraryTy' is imported by this file as 'private' from '_OverlayLibrary'}}
58+
59+
60+
//--- InternalVsPrivate.swift
61+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/InternalVsPrivate.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -verify
62+
63+
internal import DeclaringLibrary
64+
private import BystandingLibrary
65+
66+
internal func fn(_: OverlayLibraryTy) {}
67+
// expected-error @-1 {{function cannot be declared internal because its parameter uses a private type}}
68+
// expected-note @-2 {{struct 'OverlayLibraryTy' is imported by this file as 'private' from '_OverlayLibrary'}}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/// Check cross-import overlays with non-public imports.
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: cp -r %S/Inputs/lib-templates/* %t/
5+
// RUN: split-file --leading-lines %s %t
6+
7+
//--- BothPublic.swift
8+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/BothPublic.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
9+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
10+
// RUN: %FileCheck %t/BothPublic.swift < %t.swiftinterface
11+
12+
public import DeclaringLibrary
13+
public import BystandingLibrary
14+
15+
// CHECK: // swift-interface-format-version
16+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
17+
// CHECK-DAG: import Swift
18+
// CHECK-DAG: import DeclaringLibrary
19+
// CHECK-DAG: import BystandingLibrary
20+
// CHECK-DAG: import _OverlayLibrary
21+
22+
23+
//--- BothHidden.swift
24+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/BothHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
25+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
26+
// RUN: %FileCheck %t/BothHidden.swift < %t.swiftinterface
27+
// RUN: %FileCheck -check-prefix NEGATIVE %t/BothHidden.swift < %t.swiftinterface
28+
29+
internal import DeclaringLibrary
30+
internal import BystandingLibrary
31+
32+
// CHECK: // swift-interface-format-version
33+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
34+
// CHECK-DAG: import Swift
35+
// NEGATIVE-NOT: import DeclaringLibrary
36+
// NEGATIVE-NOT: import BystandingLibrary
37+
// NEGATIVE-NOT: import _OverlayLibrary
38+
39+
40+
//--- FirstHidden.swift
41+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/FirstHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
42+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
43+
// RUN: %FileCheck %t/FirstHidden.swift < %t.swiftinterface
44+
// RUN: %FileCheck -check-prefix NEGATIVE %t/FirstHidden.swift < %t.swiftinterface
45+
46+
internal import DeclaringLibrary
47+
public import BystandingLibrary
48+
49+
// CHECK: // swift-interface-format-version
50+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
51+
// CHECK-DAG: import Swift
52+
// CHECK-DAG: import BystandingLibrary
53+
// NEGATIVE-NOT: import DeclaringLibrary
54+
// NEGATIVE-NOT: import _OverlayLibrary
55+
56+
57+
//--- SecondHidden.swift
58+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/SecondHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
59+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
60+
// RUN: %FileCheck %t/SecondHidden.swift < %t.swiftinterface
61+
// RUN: %FileCheck -check-prefix NEGATIVE %t/SecondHidden.swift < %t.swiftinterface
62+
63+
public import DeclaringLibrary
64+
internal import BystandingLibrary
65+
66+
// CHECK: // swift-interface-format-version
67+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
68+
// CHECK-DAG: import Swift
69+
// CHECK-DAG: import DeclaringLibrary
70+
// NEGATIVE-NOT: import BystandingLibrary
71+
// NEGATIVE-NOT: import _OverlayLibrary
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/// Check cross-import overlays with @_spiOnly imports.
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: cp -r %S/Inputs/lib-templates/* %t/
5+
// RUN: split-file --leading-lines %s %t
6+
7+
//--- BothPublic.swift
8+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/BothPublic.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -emit-private-module-interface-path %t.private.swiftinterface -swift-version 6
9+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
10+
// RUN: %target-swift-typecheck-module-from-interface(%t.private.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
11+
// RUN: %FileCheck %t/BothPublic.swift < %t.swiftinterface
12+
// RUN: %FileCheck %t/BothPublic.swift < %t.private.swiftinterface
13+
14+
import DeclaringLibrary
15+
import BystandingLibrary
16+
17+
// CHECK: // swift-interface-format-version
18+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
19+
// CHECK-DAG: import Swift
20+
// CHECK-DAG: import DeclaringLibrary
21+
// CHECK-DAG: import BystandingLibrary
22+
// CHECK-DAG: import _OverlayLibrary
23+
24+
25+
//--- BothHidden.swift
26+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/BothHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -emit-private-module-interface-path %t.private.swiftinterface -swift-version 6
27+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
28+
// RUN: %target-swift-typecheck-module-from-interface(%t.private.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
29+
// RUN: %FileCheck %t/BothHidden.swift < %t.swiftinterface
30+
// RUN: %FileCheck -check-prefix NEGATIVE %t/BothHidden.swift < %t.swiftinterface
31+
// RUN: %FileCheck -check-prefixes CHECK,PRIVATE %t/BothHidden.swift < %t.private.swiftinterface
32+
33+
@_spiOnly import DeclaringLibrary
34+
@_spiOnly import BystandingLibrary
35+
36+
// CHECK: // swift-interface-format-version
37+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
38+
// CHECK-DAG: import Swift
39+
// NEGATIVE-NOT: import DeclaringLibrary
40+
// NEGATIVE-NOT: import BystandingLibrary
41+
// NEGATIVE-NOT: import _OverlayLibrary
42+
// PRIVATE-DAG: import DeclaringLibrary
43+
// PRIVATE-DAG: import BystandingLibrary
44+
// PRIVATE-DAG: import _OverlayLibrary
45+
46+
47+
//--- FirstHidden.swift
48+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/FirstHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -emit-private-module-interface-path %t.private.swiftinterface -swift-version 6
49+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
50+
// RUN: %target-swift-typecheck-module-from-interface(%t.private.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
51+
// RUN: %FileCheck %t/FirstHidden.swift < %t.swiftinterface
52+
// RUN: %FileCheck -check-prefix NEGATIVE %t/FirstHidden.swift < %t.swiftinterface
53+
// RUN: %FileCheck -check-prefixes CHECK,PRIVATE %t/FirstHidden.swift < %t.private.swiftinterface
54+
55+
@_spiOnly import DeclaringLibrary
56+
import BystandingLibrary
57+
58+
// CHECK: // swift-interface-format-version
59+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
60+
// CHECK-DAG: import Swift
61+
// CHECK-DAG: import BystandingLibrary
62+
// NEGATIVE-NOT: import DeclaringLibrary
63+
// NEGATIVE-NOT: import _OverlayLibrary
64+
// PRIVATE-DAG: import DeclaringLibrary
65+
// PRIVATE-DAG: import _OverlayLibrary
66+
67+
68+
//--- SecondHidden.swift
69+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %t/SecondHidden.swift -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary -emit-private-module-interface-path %t.private.swiftinterface -swift-version 6
70+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
71+
// RUN: %target-swift-typecheck-module-from-interface(%t.private.swiftinterface) -enable-cross-import-overlays -I %t/lib/swift -module-name ClientLibrary
72+
// RUN: %FileCheck %t/SecondHidden.swift < %t.swiftinterface
73+
// RUN: %FileCheck -check-prefix NEGATIVE %t/SecondHidden.swift < %t.swiftinterface
74+
// RUN: %FileCheck -check-prefixes CHECK,PRIVATE %t/SecondHidden.swift < %t.private.swiftinterface
75+
76+
import DeclaringLibrary
77+
@_spiOnly import BystandingLibrary
78+
79+
// CHECK: // swift-interface-format-version
80+
// CHECK: // swift-module-flags: {{.*}} -module-name ClientLibrary
81+
// CHECK-DAG: import Swift
82+
// CHECK-DAG: import DeclaringLibrary
83+
// NEGATIVE-NOT: import BystandingLibrary
84+
// NEGATIVE-NOT: import _OverlayLibrary
85+
// PRIVATE-DAG: import BystandingLibrary
86+
// PRIVATE-DAG: import _OverlayLibrary

0 commit comments

Comments
 (0)