Skip to content

Commit 53e8940

Browse files
authored
Merge pull request #73124 from apple/elsh/pkg-frozen
Allow @Frozen and @_fixed_layout for package access level.
2 parents df63a18 + 0a9b7b9 commit 53e8940

File tree

6 files changed

+175
-22
lines changed

6 files changed

+175
-22
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6796,18 +6796,18 @@ WARNING(discardable_result_on_void_never_function, none,
67966796
//------------------------------------------------------------------------------
67976797

67986798
ERROR(fixed_layout_attr_on_internal_type,
6799-
none, "'@_fixed_layout' attribute can only be applied to '@usableFromInline' "
6800-
"or public declarations, but %0 is "
6801-
"%select{private|fileprivate|internal|package|%error|%error}1",
6799+
none, "'@_fixed_layout' attribute can only be applied to '@usableFromInline', "
6800+
"package, or public declarations, but %0 is "
6801+
"%select{private|fileprivate|internal|%error|%error|%error}1",
68026802
(DeclName, AccessLevel))
68036803

68046804
WARNING(fixed_layout_struct,
68056805
none, "'@frozen' attribute is now used for fixed-layout structs", ())
68066806

68076807
ERROR(frozen_attr_on_internal_type,
6808-
none, "'@frozen' attribute can only be applied to '@usableFromInline' "
6809-
"or public declarations, but %0 is "
6810-
"%select{private|fileprivate|internal|package|%error|%error}1",
6808+
none, "'@frozen' attribute can only be applied to '@usableFromInline', "
6809+
"package, or public declarations, but %0 is "
6810+
"%select{private|fileprivate|internal|%error|%error|%error}1",
68116811
(DeclName, AccessLevel))
68126812

68136813
ERROR(usable_from_inline_attr_with_explicit_access,
@@ -6899,8 +6899,8 @@ ERROR(inlinable_dynamic_not_supported,
68996899
none, "'@inlinable' attribute cannot be applied to 'dynamic' declarations", ())
69006900

69016901
ERROR(inlinable_decl_not_public,
6902-
none, "'@inlinable' attribute can only be applied to public declarations, "
6903-
"but %0 is %select{private|fileprivate|internal|package|%error|%error}1",
6902+
none, "'@inlinable' attribute can only be applied to internal, package, or public declarations, "
6903+
"but %0 is %select{private|fileprivate|%error|%error|%error|%error}1",
69046904
(DeclBaseName, AccessLevel))
69056905

69066906
ERROR(inlinable_resilient_deinit,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3187,7 +3187,7 @@ void AttributeChecker::visitFixedLayoutAttr(FixedLayoutAttr *attr) {
31873187

31883188
auto *VD = cast<ValueDecl>(D);
31893189

3190-
if (VD->getFormalAccess() < AccessLevel::Public &&
3190+
if (VD->getFormalAccess() < AccessLevel::Package &&
31913191
!VD->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
31923192
diagnoseAndRemoveAttr(attr, diag::fixed_layout_attr_on_internal_type,
31933193
VD->getName(), VD->getFormalAccess());
@@ -3246,7 +3246,8 @@ void AttributeChecker::visitInlinableAttr(InlinableAttr *attr) {
32463246
return;
32473247
}
32483248

3249-
// @inlinable can only be applied to public or internal declarations.
3249+
// @inlinable can only be applied to public, package, or
3250+
// internal declarations.
32503251
auto access = VD->getFormalAccess();
32513252
if (access < AccessLevel::Internal) {
32523253
diagnoseAndRemoveAttr(attr, diag::inlinable_decl_not_public,
@@ -3953,7 +3954,7 @@ void AttributeChecker::visitFrozenAttr(FrozenAttr *attr) {
39533954
return;
39543955
}
39553956

3956-
if (ED->getFormalAccess() < AccessLevel::Public &&
3957+
if (ED->getFormalAccess() < AccessLevel::Package &&
39573958
!ED->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
39583959
diagnoseAndRemoveAttr(attr, diag::enum_frozen_nonpublic, attr);
39593960
return;
@@ -3962,7 +3963,9 @@ void AttributeChecker::visitFrozenAttr(FrozenAttr *attr) {
39623963

39633964
auto *VD = cast<ValueDecl>(D);
39643965

3965-
if (VD->getFormalAccess() < AccessLevel::Public &&
3966+
// @frozen attribute is allowed for public, package, or
3967+
// usableFromInline decls.
3968+
if (VD->getFormalAccess() < AccessLevel::Package &&
39663969
!VD->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
39673970
diagnoseAndRemoveAttr(attr, diag::frozen_attr_on_internal_type,
39683971
VD->getName(), VD->getFormalAccess());
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %target-swift-frontend -typecheck %s -I %t -swift-version 5 -package-name mypkg -verify
2+
3+
package struct PkgStruct {
4+
package var one: Int
5+
package var two: String
6+
package func f() {}
7+
}
8+
9+
@frozen
10+
package struct FrozenPkgStruct {
11+
package var one: Int
12+
package var two: String
13+
package func f() {}
14+
}
15+
16+
@frozen
17+
@usableFromInline
18+
package struct FrozenUfiPkgStruct {
19+
package var one: Int
20+
package var two: String
21+
package func f() {}
22+
}
23+
24+
@frozen // expected-error {{'@frozen' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FrozenInternalStruct' is internal}} {{1-9=}}
25+
struct FrozenInternalStruct {
26+
var one: Int
27+
var two: String
28+
func f() {}
29+
}
30+
31+
@_fixed_layout
32+
package class FixedPkgKlass {
33+
package var one: Int = 1
34+
package var two: String = ""
35+
package func f() {}
36+
}
37+
38+
@_fixed_layout // expected-error {{'@_fixed_layout' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FixedInternalKlass' is internal}} {{1-16=}}
39+
class FixedInternalKlass {
40+
var one: Int = 1
41+
var two: String = ""
42+
func f() {}
43+
}
44+

test/Sema/package_resilience_bypass_exhaustive_switch.swift

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// RUN: -experimental-allow-non-resilient-access \
99
// RUN: -emit-module -emit-module-path %t/Utils.swiftmodule
1010

11+
// RUN: %target-swift-frontend -typecheck %t/Utils.swift -I %t -swift-version 5 -package-name mypkg -verify
12+
1113
// RUN: %target-swift-frontend -typecheck %t/ClientDefault.swift -I %t -swift-version 5 -package-name mypkg -verify
1214

1315
// RUN: %target-swift-frontend -typecheck %t/ClientOptimized.swift -I %t -swift-version 5 -package-name mypkg -experimental-package-bypass-resilience -verify
@@ -19,6 +21,19 @@ package enum PkgEnum {
1921
case two(Int)
2022
}
2123

24+
@frozen
25+
package enum FrozenPkgEnum {
26+
case one
27+
case two(Int)
28+
}
29+
30+
@frozen
31+
@usableFromInline
32+
package enum FrozenUfiPkgEnum {
33+
case one
34+
case two(Int)
35+
}
36+
2237
@usableFromInline
2338
package enum UfiPkgEnum {
2439
case one
@@ -36,6 +51,61 @@ public enum FrozenPublicEnum {
3651
case two(Int)
3752
}
3853

54+
package func uf(_ arg: PkgEnum) -> Int {
55+
switch arg { // no-warning
56+
case .one:
57+
return 1
58+
case .two(let val):
59+
return 2 + val
60+
}
61+
}
62+
63+
package func um(_ arg: FrozenPkgEnum) -> Int {
64+
switch arg { // no-warning
65+
case .one:
66+
return 1
67+
case .two(let val):
68+
return 2 + val
69+
}
70+
}
71+
72+
package func un(_ arg: FrozenUfiPkgEnum) -> Int {
73+
switch arg { // no-warning
74+
case .one:
75+
return 1
76+
case .two(let val):
77+
return 2 + val
78+
}
79+
}
80+
81+
package func ug(_ arg: UfiPkgEnum) -> Int {
82+
switch arg { // no-warning
83+
case .one:
84+
return 1
85+
case .two(let val):
86+
return 2 + val
87+
}
88+
}
89+
90+
public func uh(_ arg: PublicEnum) -> Int {
91+
switch arg { // no-warning
92+
case .one:
93+
return 1
94+
case .two(let val):
95+
return 2 + val
96+
}
97+
}
98+
99+
public func uk(_ arg: FrozenPublicEnum) -> Int {
100+
switch arg { // no-warning
101+
case .one:
102+
return 1
103+
case .two(let val):
104+
return 2 + val
105+
}
106+
}
107+
108+
39109
//--- ClientDefault.swift
40110
import Utils
41111

@@ -48,6 +118,24 @@ package func f(_ arg: PkgEnum) -> Int {
48118
}
49119
}
50120

121+
package func m(_ arg: FrozenPkgEnum) -> Int {
122+
switch arg { // no-warning
123+
case .one:
124+
return 1
125+
case .two(let val):
126+
return 2 + val
127+
}
128+
}
129+
130+
package func n(_ arg: FrozenUfiPkgEnum) -> Int {
131+
switch arg { // no-warning
132+
case .one:
133+
return 1
134+
case .two(let val):
135+
return 2 + val
136+
}
137+
}
138+
51139
package func g(_ arg: UfiPkgEnum) -> Int {
52140
switch arg { // expected-warning {{switch covers known cases, but 'UfiPkgEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
53141
case .one:
@@ -80,8 +168,8 @@ public func k(_ arg: FrozenPublicEnum) -> Int {
80168
import Utils
81169

82170
// With optimization enabled to bypass resilience checks within
83-
// a package boundary, public (non-frozen) or package enums no
84-
// longer require `@unknown default` in source code switch stmts.
171+
// a package boundary, public (non-frozen) or package (non-frozen)
172+
// enums no longer require `@unknown default` in switch stmts.
85173
package func f(_ arg: PkgEnum) -> Int {
86174
switch arg { // no-warning
87175
case .one:
@@ -91,6 +179,24 @@ package func f(_ arg: PkgEnum) -> Int {
91179
}
92180
}
93181

182+
package func m(_ arg: FrozenPkgEnum) -> Int {
183+
switch arg { // no-warning
184+
case .one:
185+
return 1
186+
case .two(let val):
187+
return 2 + val
188+
}
189+
}
190+
191+
package func n(_ arg: FrozenUfiPkgEnum) -> Int {
192+
switch arg { // no-warning
193+
case .one:
194+
return 1
195+
case .two(let val):
196+
return 2 + val
197+
}
198+
}
199+
94200
package func g(_ arg: UfiPkgEnum) -> Int {
95201
switch arg { // no-warning
96202
case .one:

test/attr/attr_fixed_layout.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,31 @@ struct Rectangle {
6969
//
7070

7171
@frozen struct InternalStruct { // expected-note * {{declared here}}
72-
// expected-error@-1 {{'@frozen' attribute can only be applied to '@usableFromInline' or public declarations, but 'InternalStruct' is internal}}
72+
// expected-error@-1 {{'@frozen' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'InternalStruct' is internal}}
7373

7474
@frozen public struct NestedStruct {}
7575
}
7676

7777
@_fixed_layout struct FixedInternalStruct { // expected-note * {{declared here}}
78-
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@usableFromInline' or public declarations, but 'FixedInternalStruct' is internal}}
78+
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FixedInternalStruct' is internal}}
7979
// expected-warning@-2 {{'@frozen' attribute is now used for fixed-layout structs}}
8080

8181
@_fixed_layout public struct NestedStruct {}
8282
// expected-warning@-1 {{'@frozen' attribute is now used for fixed-layout structs}}
8383
}
8484

8585
@frozen fileprivate struct FileprivateStruct {}
86-
// expected-error@-1 {{'@frozen' attribute can only be applied to '@usableFromInline' or public declarations, but 'FileprivateStruct' is fileprivate}}
86+
// expected-error@-1 {{'@frozen' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FileprivateStruct' is fileprivate}}
8787

8888
@_fixed_layout fileprivate struct FixedFileprivateStruct {}
89-
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@usableFromInline' or public declarations, but 'FixedFileprivateStruct' is fileprivate}}
89+
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FixedFileprivateStruct' is fileprivate}}
9090
// expected-warning@-2 {{'@frozen' attribute is now used for fixed-layout structs}}
9191

9292
@frozen private struct PrivateStruct {} // expected-note * {{declared here}}
93-
// expected-error@-1 {{'@frozen' attribute can only be applied to '@usableFromInline' or public declarations, but 'PrivateStruct' is private}}
93+
// expected-error@-1 {{'@frozen' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'PrivateStruct' is private}}
9494

9595
@_fixed_layout private struct FixedPrivateStruct {} // expected-note * {{declared here}}
96-
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@usableFromInline' or public declarations, but 'FixedPrivateStruct' is private}}
96+
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FixedPrivateStruct' is private}}
9797
// expected-warning@-2 {{'@frozen' attribute is now used for fixed-layout structs}}
9898

9999

test/attr/attr_inlinable.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public struct Struct {
109109

110110
@inlinable
111111
private func privateInlinableMethod() {
112-
// expected-error@-2 {{'@inlinable' attribute can only be applied to public declarations, but 'privateInlinableMethod' is private}}
112+
// expected-error@-2 {{'@inlinable' attribute can only be applied to internal, package, or public declarations, but 'privateInlinableMethod' is private}}
113113
struct Nested {}
114114
// expected-error@-1 {{type 'Nested' cannot be nested inside an '@inlinable' function}}
115115
}
@@ -326,7 +326,7 @@ extension P {
326326

327327
// rdar://problem/60605117
328328
public struct PrivateInlinableCrash {
329-
@inlinable // expected-error {{'@inlinable' attribute can only be applied to public declarations, but 'formatYesNo' is private}}
329+
@inlinable // expected-error {{'@inlinable' attribute can only be applied to internal, package, or public declarations, but 'formatYesNo' is private}}
330330
private func formatYesNo(_ value: Bool) -> String {
331331
value ? "YES" : "NO"
332332
}

0 commit comments

Comments
 (0)