Skip to content

Commit da3c12e

Browse files
authored
Merge pull request #72871 from tshortli/extension-import-visibility
stdlib: Adopt `ExtensionImportVisibility` experimental feature
2 parents 7d72a62 + d0571af commit da3c12e

15 files changed

+102
-7
lines changed

include/swift/Basic/Features.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ CONDITIONALLY_SUPPRESSIBLE_EXPERIMENTAL_FEATURE(IsolatedAny, true)
367367

368368

369369
// Whether members of extensions respect the enclosing file's imports.
370-
EXPERIMENTAL_FEATURE(ExtensionImportVisibility, true)
370+
EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE(ExtensionImportVisibility, true)
371371

372372
// Alias for IsolatedAny
373373
EXPERIMENTAL_FEATURE(IsolatedAny2, true)

stdlib/cmake/modules/SwiftSource.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,8 @@ function(_compile_swift_files
628628
list(APPEND swift_flags "-enable-experimental-feature" "NonescapableTypes")
629629
endif()
630630

631+
list(APPEND swift_flags "-enable-experimental-feature" "ExtensionImportVisiblity")
632+
631633
if (SWIFT_STDLIB_ENABLE_STRICT_CONCURRENCY_COMPLETE)
632634
list(APPEND swift_flags "-strict-concurrency=complete")
633635
endif()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@import Foundation;
2+
3+
@interface X
4+
@end
5+
6+
@interface X (A)
7+
- (void)fromA;
8+
@end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@_exported import Categories_A
2+
3+
extension X {
4+
public func fromOverlayForA() {}
5+
@objc public func fromOverlayForAObjC() {}
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import Categories_A;
2+
3+
@interface X (B)
4+
- (void)fromB;
5+
@end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@_exported import Categories_B
2+
3+
extension X {
4+
public func fromOverlayForB() {}
5+
@objc public func fromOverlayForBObjC() {}
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import Categories_A;
2+
3+
@interface X (C)
4+
- (void)fromC;
5+
@end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@_exported import Categories_C
2+
3+
extension X {
4+
public func fromOverlayForC() {}
5+
@objc public func fromOverlayForCObjC() {}
6+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import Categories_C
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module Categories_A {
2+
header "Categories_A.h"
3+
export *
4+
}
5+
6+
module Categories_B {
7+
header "Categories_B.h"
8+
export *
9+
}
10+
11+
module Categories_C {
12+
header "Categories_C.h"
13+
export *
14+
}

test/NameLookup/Inputs/extensions_A.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,11 @@ public struct Y<T> { }
77
extension Y: P where T: P { }
88

99
public struct Z: P { }
10+
11+
extension X {
12+
public func XinA() { }
13+
}
14+
15+
extension Y {
16+
public func YinA() { }
17+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import extensions_A
22

3-
public extension X {
3+
extension X {
44
public func XinB() { }
55
}
66

7-
public extension Y {
7+
extension Y {
88
public func YinB() { }
99
}
1010

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import extensions_A
1+
@_exported import extensions_A
22
import extensions_B
33

4-
public extension X {
4+
extension X {
55
public func XinC() { }
66
}
77

8-
public extension Y {
8+
extension Y {
99
public func YinC() { }
1010
}
1111

test/NameLookup/extensions_transitive.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
// RUN: %target-swift-frontend -emit-module -I %t -o %t %S/Inputs/extensions_C.swift
55
// RUN: %target-swift-frontend -typecheck %s -I %t -verify -enable-experimental-feature ExtensionImportVisibility
66

7-
import extensions_A
87
import extensions_C
98
// expected-note 2{{add import of module 'extensions_B'}}{{1-1=import extensions_B\n}}
109
func test(x: X, y: Y<Z>) {
10+
x.XinA()
11+
y.YinA()
12+
1113
x.XinB() // expected-error{{instance method 'XinB()' is not available due to missing import of defining module 'extensions_B'}}
1214
y.YinB() // expected-error{{instance method 'YinB()' is not available due to missing import of defining module 'extensions_B'}}
1315

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -I %t -I %S/Inputs/Categories -o %t %S/Inputs/Categories/Categories_A.swift
3+
// RUN: %target-swift-frontend -emit-module -I %t -I %S/Inputs/Categories -o %t %S/Inputs/Categories/Categories_B.swift
4+
// RUN: %target-swift-frontend -emit-module -I %t -I %S/Inputs/Categories -o %t %S/Inputs/Categories/Categories_C.swift
5+
// RUN: %target-swift-frontend -emit-module -I %t -I %S/Inputs/Categories -o %t %S/Inputs/Categories/Categories_D.swift
6+
// RUN: %target-swift-frontend -typecheck %s -I %t -I %S/Inputs/Categories -verify -enable-experimental-feature ExtensionImportVisibility
7+
8+
// REQUIRES: objc_interop
9+
10+
import Categories_B
11+
import Categories_D
12+
// expected-note 2 {{add import of module 'Categories_C'}}{{1-1=import Categories_C\n}}
13+
func test(x: X) {
14+
x.fromA()
15+
x.fromOverlayForA()
16+
x.fromB()
17+
x.fromOverlayForB()
18+
x.fromC() // expected-error {{class method 'fromC()' is not available due to missing import of defining module 'Categories_C'}}
19+
x.fromOverlayForC() // expected-error {{instance method 'fromOverlayForC()' is not available due to missing import of defining module 'Categories_C'}}
20+
}
21+
22+
func testAnyObject(a: AnyObject) {
23+
a.fromA()
24+
a.fromOverlayForAObjC()
25+
a.fromB()
26+
a.fromOverlayForBObjC()
27+
// FIXME: Better diagnostics?
28+
// Name lookup for AnyObject already ignored transitive imports, so
29+
// ExtensionImportVisibility has no effect on these diagnostics.
30+
a.fromC() // expected-error {{value of type 'AnyObject' has no member 'fromC'}}
31+
a.fromOverlayForCObjC() // expected-error {{value of type 'AnyObject' has no member 'fromOverlayForCObjC'}}
32+
}

0 commit comments

Comments
 (0)