Skip to content

Commit 772e42e

Browse files
committed
Add a missing check for a corner case with package use site / internal decl site
Update tests Resolves rdar://106732804, rdar://104987455
1 parent f3524ad commit 772e42e

File tree

5 files changed

+112
-89
lines changed

5 files changed

+112
-89
lines changed

lib/AST/Decl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4112,6 +4112,11 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD,
41124112
}
41134113
return true;
41144114
case AccessLevel::Internal: {
4115+
// Invalid if the use site is > Internal.
4116+
// E.g. extension containing a member of a protocol it conforms to has
4117+
// `package` access level but the member is `internal`
4118+
if (useDC->getContextKind() == DeclContextKind::Package)
4119+
return false;
41154120
const ModuleDecl *sourceModule = sourceDC->getParentModule();
41164121
const DeclContext *useFile = useDC->getModuleScopeContext();
41174122
if (useFile->getParentModule() == sourceModule)

test/Sema/accessibility.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,11 @@ public class DerivedFromInternalConcreteGenericComposition : InternalConcreteGen
14711471
public func publicReq() {}
14721472
}
14731473

1474-
// FIXME: rdar://104987455 should have expected note and error 'class cannot be declared public because its superclass is internal'
1474+
fileprivate typealias FilePrivateConcreteGenericCompositionPkg = InternalGenericClass<Int> & InternalProto
1475+
public class DerivedFromFilePrivateConcreteGenericCompositionPkg : FilePrivateConcreteGenericCompositionPkg { // expected-error {{class cannot be declared public because its superclass uses an internal type as a generic parameter}}
1476+
public func internalReq() {}
1477+
}
1478+
14751479
internal typealias InternalConcreteGenericCompositionPkg = PackageGenericClass<Int> & PackageProto
14761480
public class DerivedFromInternalConcreteGenericCompositionPkg : InternalConcreteGenericCompositionPkg { // expected-error {{class cannot be declared public because its superclass uses a package type as a generic parameter}}
14771481
public func packageReq() {}

test/Sema/accessibility_package.swift

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,18 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %{python} %utils/split_file.py -o %t %s
2+
// RUN: split-file %s %t
33

4-
// RUN: %target-swift-frontend -module-name Utils %t/Utils.swift -emit-module -emit-module-path %t/Utils.swiftmodule -package-name myLib
4+
// RUN: %target-swift-frontend -verify -module-name Utils %t/Utils.swift -emit-module -emit-module-path %t/Utils.swiftmodule -package-name myLib
55
// RUN: test -f %t/Utils.swiftmodule
66

7-
// RUN: %target-swift-frontend -module-name LibGood %t/LibGood.swift -emit-module -emit-module-path %t/LibGood.swiftmodule -package-name myLib -I %t
7+
// RUN: %target-swift-frontend -verify -module-name LibGood %t/LibGood.swift -emit-module -emit-module-path %t/LibGood.swiftmodule -package-name myLib -I %t
88
// RUN: test -f %t/LibGood.swiftmodule
99

10-
// RUN: not %target-swift-frontend -module-name Client %t/Client.swift -emit-module -emit-module-path %t/Client.swiftmodule -package-name client -I %t 2> %t/resultClient.output
11-
// RUN: %FileCheck %s -input-file %t/resultClient.output -check-prefix CHECK-CLIENT
12-
// CHECK-CLIENT: error: 'pkgVar' is inaccessible due to 'package' protection level
13-
// CHECK-CLIENT: error: 'pkgFunc' is inaccessible due to 'package' protection level
10+
// RUN: %target-swift-frontend -verify -module-name Client %t/Client.swift -emit-module -emit-module-path %t/Client.swiftmodule -package-name client -I %t
1411

15-
// RUN: not %target-swift-frontend -typecheck %t/Lib.swift -package-name myLib -I %t 2> %t/result1.output
16-
// RUN: %FileCheck %s -input-file %t/result1.output -check-prefix CHECK-1
17-
// CHECK-1: error: overriding non-open instance method outside of its defining module
18-
// CHECK-1: error: overriding non-open instance method outside of its defining module
19-
// CHECK-1: error: cannot inherit from non-open class 'PublicKlass' outside of its defining module
20-
// CHECK-1: error: cannot inherit from non-open class 'PackageKlass' outside of its defining module
21-
// CHECK-1: error: cannot assign to property: 'publicGetInternal' setter is inaccessible
22-
// CHECK-1: error: cannot assign to property: 'pkgVar' setter is inaccessible
12+
// RUN: %target-swift-frontend -typecheck -verify %t/LibSamePackage.swift -package-name myLib -I %t
13+
// RUN: %target-swift-frontend -typecheck -verify %t/LibOtherPackage.swift -package-name "otherLib" -I %t
2314

24-
// RUN: not %target-swift-frontend -typecheck %t/Lib.swift -package-name "otherLib" -I %t 2> %t/result2.output
25-
// %FileCheck %s -input-file %t/result2.output -check-prefix CHECK-2
26-
// CHECK-2: error: cannot find type 'PackageProto' in scope
27-
// CHECK-2: error: 'pkgFunc' is inaccessible due to 'package' protection level
28-
// CHECK-2: error: cannot find 'PackageKlass' in scope
29-
30-
31-
// BEGIN Utils.swift
15+
//--- Utils.swift
3216
package protocol PackageProto {
3317
var pkgVar: Double { get set }
3418
func pkgFunc()
@@ -59,40 +43,52 @@ open class OpenKlass {
5943
package func packageFunc() {}
6044
}
6145

62-
// BEGIN Lib.swift
46+
//--- LibSamePackage.swift
6347
import Utils
6448

6549
// Test accessing public and package decls
6650
public func test() {
6751
let x = PublicKlass()
6852
x.publicFunc()
69-
x.pkgFunc() // Allowed if in same package
70-
x.publicGetPkg = 3 // Allowed if in same package
71-
x.publicGetInternal = 4 // Not allowed
53+
x.pkgFunc() // OK
54+
x.publicGetPkg = 3 // OK
55+
x.publicGetInternal = 4 // expected-error {{cannot assign to property: 'publicGetInternal' setter is inaccessible}}
7256

73-
let y = PackageKlass() // Allowed if in same package
74-
y.pkgVar = 1.5 // Not allowed
75-
y.pkgFunc() // Allowed if in same package
57+
let y = PackageKlass() // OK
58+
y.pkgVar = 1.5 // expected-error {{cannot assign to property: 'pkgVar' setter is inaccessible}}
59+
y.pkgFunc() // OK
7660
}
7761

7862
// Test conformance to a package protocol
79-
package struct LibStruct : PackageProto { // Allowed if in same package
63+
package struct LibStruct : PackageProto { // OK
8064
package var pkgVar: Double = 1.0
8165
package func pkgFunc() {}
8266
}
8367

8468
// Test subclassing / overrides
8569
class SubOpenKlass: OpenKlass {
8670
override open func openFunc() {}
87-
override public func publicFunc() {}
88-
override package func packageFunc() {}
71+
override public func publicFunc() {} // expected-error {{overriding non-open instance method outside of its defining module}}
72+
override package func packageFunc() {} // expected-error {{overriding non-open instance method outside of its defining module}}
8973
}
90-
class SubPublicKlass: PublicKlass {} // Not allowed
91-
class SubPackageKlass: PackageKlass {} // Not allowed
74+
class SubPublicKlass: PublicKlass {} // expected-error {{cannot inherit from non-open class 'PublicKlass' outside of its defining module}}
75+
class SubPackageKlass: PackageKlass {} // expected-error {{cannot inherit from non-open class 'PackageKlass' outside of its defining module}}
76+
77+
78+
//--- LibOtherPackage.swift
79+
import Utils
9280

81+
// Test accessing package decls
82+
public func test() {
83+
let x = PublicKlass()
84+
x.publicFunc() // OK
85+
x.pkgFunc() // expected-error {{'pkgFunc' is inaccessible due to 'package' protection level}}
86+
let y = PackageKlass() // expected-error {{cannot find 'PackageKlass' in scope}}
87+
}
9388

89+
package struct LibStruct : PackageProto {} // expected-error {{cannot find type 'PackageProto' in scope}}
9490

95-
// BEGIN LibGood.swift
91+
//--- LibGood.swift
9692
import Utils
9793

9894
public func libFunc() {
@@ -107,13 +103,13 @@ public struct LibStruct: PackageProto {
107103
public func publicFunc() {}
108104
}
109105

110-
// BEGIN Client.swift
106+
//--- Client.swift
111107
import LibGood
112108

113109
func clientFunc() {
114110
let lib = LibStruct()
115-
_ = lib.pkgVar // Not allowed
111+
_ = lib.pkgVar // expected-error {{'pkgVar' is inaccessible due to 'package' protection level}}
116112
_ = lib.publicVar
117-
lib.pkgFunc() // Not allowed
113+
lib.pkgFunc() // expected-error {{'pkgFunc' is inaccessible due to 'package' protection level}}
118114
lib.publicFunc()
119115
}

test/Sema/accessibility_package_inline.swift

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,22 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %{python} %utils/split_file.py -o %t %s
2+
// RUN: split-file %s %t
33

4-
// RUN: %target-swift-frontend -module-name UtilsGood %t/UtilsGood.swift -emit-module -emit-module-path %t/UtilsGood.swiftmodule -package-name myLib
4+
// RUN: %target-swift-frontend -verify -module-name UtilsGood %t/UtilsGood.swift -emit-module -emit-module-path %t/UtilsGood.swiftmodule -package-name myLib
55
// RUN: test -f %t/UtilsGood.swiftmodule
66

7-
// RUN: not %target-swift-frontend -typecheck %t/Utils.swift -package-name myLib -I %t 2> %t/resultUtils.output
8-
// RUN: %FileCheck %s -input-file %t/resultUtils.output -check-prefix CHECK-UTILS
9-
// CHECK-UTILS: error: class 'PackageKlass' is package and cannot be referenced from an '@inlinable' function
10-
// CHECK-UTILS: let a = PackageKlass()
11-
// CHECK-UTILS: ^
12-
// CHECK-UTILS: note: class 'PackageKlass' is not '@usableFromInline' or public
13-
// CHECK-UTILS: package class PackageKlass {
14-
// CHECK-UTILS: ^
15-
// CHECK-UTILS: error: initializer 'init()' is package and cannot be referenced from an '@inlinable' function
16-
// CHECK-UTILS: let a = PackageKlass() // should error
17-
// CHECK-UTILS: ^
18-
// CHECK-UTILS: note: initializer 'init()' is not '@usableFromInline' or public
19-
// CHECK-UTILS: package init() {}
20-
// CHECK-UTILS: ^
21-
// CHECK-UTILS: error: class 'InternalKlass' is internal and cannot be referenced from an '@inlinable' function
22-
// CHECK-UTILS: let b = InternalKlass() // should error
23-
// CHECK-UTILS: ^
24-
// CHECK-UTILS: note: class 'InternalKlass' is not '@usableFromInline' or public
25-
// CHECK-UTILS: class InternalKlass {
26-
// CHECK-UTILS: ^
27-
// CHECK-UTILS: error: initializer 'init()' is internal and cannot be referenced from an '@inlinable' function
28-
// CHECK-UTILS: let b = InternalKlass() // should error
29-
// CHECK-UTILS: ^
30-
// CHECK-UTILS: note: initializer 'init()' is not '@usableFromInline' or public
31-
// CHECK-UTILS: init() {}
32-
// CHECK-UTILS: ^
33-
34-
// RUN: not %target-swift-frontend -typecheck %t/Lib.swift -package-name "otherLib" -I %t 2> %t/resultLib.output
35-
// %FileCheck %s -input-file %t/resultLib.output -check-prefix CHECK-LIB
36-
// CHECK-LIB: error: cannot find 'packageFunc' in scope
37-
// CHECK-LIB: packageFunc()
38-
// CHECK-LIB: ^~~~~~~~~~~
39-
40-
// RUN: %target-swift-frontend -module-name Lib %t/Lib.swift -emit-module -emit-module-path %t/Lib.swiftmodule -package-name myLib -I %t
41-
// RUN: test -f %t/Lib.swiftmodule
42-
43-
// BEGIN Utils.swift
7+
// RUN: %target-swift-frontend -typecheck -verify %t/Utils.swift -package-name myLib -I %t
8+
// RUN: %target-swift-frontend -typecheck -verify %t/LibOtherPackage.swift -package-name otherLib -I %t
9+
// RUN: %target-swift-frontend -typecheck -verify %t/LibSamePackage.swift -package-name myLib -I %t
10+
11+
//--- Utils.swift
4412
package protocol PackageProto {
4513
var pkgVar: Double { get set }
4614
func pkgFunc()
4715
}
4816

17+
// expected-note@+1 *{{class 'PackageKlass' is not '@usableFromInline' or public}}
4918
package class PackageKlass {
50-
package init() {}
19+
package init() {} // expected-note *{{initializer 'init()' is not '@usableFromInline' or public}}
5120
package private(set) var pkgVar: Double = 1.0
5221
package func pkgFunc() {}
5322
}
@@ -71,8 +40,10 @@ protocol InternalProto {
7140
var internalVar: Double { get set }
7241
func internalFunc()
7342
}
43+
44+
// expected-note@+1 *{{class 'InternalKlass' is not '@usableFromInline' or public}}
7445
class InternalKlass {
75-
init() {}
46+
init() {} // expected-note *{{initializer 'init()' is not '@usableFromInline' or public}}
7647
}
7748
@usableFromInline
7849
class InternalKlassProto: InternalProto {
@@ -90,8 +61,12 @@ class InternalKlassForInline {
9061

9162
@inlinable
9263
public func publicFunc() {
93-
let a = PackageKlass() // should error
64+
let a = PackageKlass()
65+
// expected-error@-1 {{class 'PackageKlass' is package and cannot be referenced from an '@inlinable' function}}
66+
// expected-error@-2 {{initializer 'init()' is package and cannot be referenced from an '@inlinable' function}}
9467
let b = InternalKlass() // should error
68+
// expected-error@-1 {{class 'InternalKlass' is internal and cannot be referenced from an '@inlinable' function}}
69+
// expected-error@-2 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
9570
let c = PackageKlassProto()
9671
let d = InternalKlassProto()
9772
let e = PackageKlassForInline()
@@ -101,8 +76,12 @@ public func publicFunc() {
10176

10277
@inlinable
10378
func internalFunc() {
104-
let a = PackageKlass() // should error
105-
let b = InternalKlass() // should error
79+
let a = PackageKlass()
80+
// expected-error@-1 {{class 'PackageKlass' is package and cannot be referenced from an '@inlinable' function}}
81+
// expected-error@-2 {{initializer 'init()' is package and cannot be referenced from an '@inlinable' function}}
82+
let b = InternalKlass()
83+
// expected-error@-1 {{class 'InternalKlass' is internal and cannot be referenced from an '@inlinable' function}}
84+
// expected-error@-2 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
10685
let c = PackageKlassProto()
10786
let d = InternalKlassProto()
10887
let e = PackageKlassForInline()
@@ -112,16 +91,20 @@ func internalFunc() {
11291

11392
@inlinable
11493
package func packageFunc() {
115-
let a = PackageKlass() // should error
116-
let b = InternalKlass() // should error
94+
let a = PackageKlass()
95+
// expected-error@-1 {{class 'PackageKlass' is package and cannot be referenced from an '@inlinable' function}}
96+
// expected-error@-2 {{initializer 'init()' is package and cannot be referenced from an '@inlinable' function}}
97+
let b = InternalKlass()
98+
// expected-error@-1 {{class 'InternalKlass' is internal and cannot be referenced from an '@inlinable' function}}
99+
// expected-error@-2 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
117100
let c = PackageKlassProto()
118101
let d = InternalKlassProto()
119102
let e = PackageKlassForInline()
120103
let f = InternalKlassForInline()
121104
print(a, b, c, d, e, f)
122105
}
123106

124-
// BEGIN UtilsGood.swift
107+
//--- UtilsGood.swift
125108
package protocol PackageProto {
126109
var pkgVar: Double { get set }
127110
func pkgFunc()
@@ -170,11 +153,20 @@ package func packageFunc() {
170153
print(x, y)
171154
}
172155

173-
// BEGIN Lib.swift
156+
//--- LibOtherPackage.swift
157+
import UtilsGood
158+
159+
@inlinable
160+
public func libFunc() {
161+
publicFunc()
162+
packageFunc() // expected-error {{cannot find 'packageFunc' in scope}}
163+
}
164+
165+
//--- LibSamePackage.swift
174166
import UtilsGood
175167

176168
@inlinable
177169
public func libFunc() {
178170
publicFunc()
179-
packageFunc() // Allowed if in same package
171+
packageFunc() // OK
180172
}

test/attr/accessibility_proto.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,29 @@ package protocol PkgEmptyInit {
243243
public struct PkgBuggy: PkgEmptyInit {
244244
// expected-error@-1 {{initializer 'init()' must be declared package because it matches a requirement in package protocol 'PkgEmptyInit'}}
245245
}
246+
247+
package protocol PkgReqProvider {}
248+
extension PkgReqProvider {
249+
fileprivate func foo() {}
250+
// expected-note@-1 {{mark the instance method as 'package' to satisfy the requirement}} {{3-14=package}}
251+
typealias AssocB = String
252+
// expected-note@-1 {{mark the type alias as 'package' to satisfy the requirement}} {{3-3=package }}
253+
}
254+
package struct PkgAdoptViaProtocol : PkgProtoWithReqs, PkgReqProvider {
255+
// expected-error@-1 {{method 'foo()' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}}
256+
// expected-error@-2 {{type alias 'AssocB' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}}
257+
package typealias AssocA = Int
258+
}
259+
260+
package protocol PkgReqProvider2 {}
261+
extension PkgProtoWithReqs where Self : PkgReqProvider2 {
262+
func foo() {}
263+
// expected-note@-1 {{mark the instance method as 'package' to satisfy the requirement}} {{3-3=package }}
264+
typealias AssocB = String
265+
// expected-note@-1 {{mark the type alias as 'package' to satisfy the requirement}} {{3-3=package }}
266+
}
267+
package struct PkgAdoptViaCombinedProtocol : PkgProtoWithReqs, PkgReqProvider2 {
268+
// expected-error@-1 {{method 'foo()' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}}
269+
// expected-error@-2 {{type alias 'AssocB' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}}
270+
public typealias AssocA = Int
271+
}

0 commit comments

Comments
 (0)