Skip to content

Commit ef321c9

Browse files
committed
Allow @usableFromInline and @inlinable to package decls
Add tests for packgae inline Add more package acl tests Resolves rdar://104617133
1 parent 0bece01 commit ef321c9

19 files changed

+1091
-89
lines changed

Diff for: include/swift/AST/DiagnosticsSema.def

+3-3
Original file line numberDiff line numberDiff line change
@@ -2439,10 +2439,10 @@ WARNING(protocol_access_warn,none,
24392439
(bool, AccessLevel, bool, AccessLevel, bool, DescriptiveDeclKind))
24402440
ERROR(protocol_usable_from_inline,none,
24412441
"protocol %select{refined|used}0 by '@usableFromInline' protocol "
2442-
"must be '@usableForInline' or public", (bool))
2442+
"must be '@usableFromInline' or public", (bool))
24432443
WARNING(protocol_usable_from_inline_warn,none,
24442444
"protocol %select{refined|used}0 by '@usableFromInline' protocol "
2445-
"should be '@usableForInline' or public", (bool))
2445+
"should be '@usableFromInline' or public", (bool))
24462446
ERROR(protocol_property_must_be_computed_var,none,
24472447
"protocols cannot require properties to be immutable; declare read-only "
24482448
"properties by using 'var' with a '{ get }' specifier", ())
@@ -6162,7 +6162,7 @@ ERROR(frozen_attr_on_internal_type,
61626162
(DeclName, AccessLevel))
61636163

61646164
ERROR(usable_from_inline_attr_with_explicit_access,
6165-
none, "'@usableFromInline' attribute can only be applied to internal "
6165+
none, "'@usableFromInline' attribute can only be applied to internal or package "
61666166
"declarations, but %0 is %select{private|fileprivate|%error|package|public|open}1",
61676167
(DeclName, AccessLevel))
61686168

Diff for: lib/AST/Decl.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -3646,7 +3646,7 @@ SourceLoc ValueDecl::getAttributeInsertionLoc(bool forModifier) const {
36463646
/// Returns true if \p VD needs to be treated as publicly-accessible
36473647
/// at the SIL, LLVM, and machine levels due to being @usableFromInline.
36483648
bool ValueDecl::isUsableFromInline() const {
3649-
assert(getFormalAccess() <= AccessLevel::Internal);
3649+
assert(getFormalAccess() < AccessLevel::Public);
36503650

36513651
if (getAttrs().hasAttribute<UsableFromInlineAttr>() ||
36523652
getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>() ||
@@ -3767,7 +3767,7 @@ static AccessLevel getAdjustedFormalAccess(const ValueDecl *VD,
37673767
return getMaximallyOpenAccessFor(VD);
37683768

37693769
if (treatUsableFromInlineAsPublic &&
3770-
access <= AccessLevel::Internal &&
3770+
access < AccessLevel::Public &&
37713771
VD->isUsableFromInline()) {
37723772
return AccessLevel::Public;
37733773
}
@@ -4073,8 +4073,9 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD,
40734073
// marked 'public' if the protocol was '@_versioned' (now
40744074
// '@usableFromInline'). Which works at the ABI level, so let's keep
40754075
// supporting that here by explicitly checking for it.
4076+
auto protoAccess = proto->getFormalAccess();
40764077
if (access == AccessLevel::Public &&
4077-
proto->getFormalAccess() == AccessLevel::Internal &&
4078+
(protoAccess == AccessLevel::Internal || protoAccess == AccessLevel::Package) &&
40784079
proto->isUsableFromInline()) {
40794080
return true;
40804081
}

Diff for: lib/Sema/TypeCheckAccess.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
12681268
: AccessControlCheckerBase(/*checkUsableFromInline=*/true) {}
12691269

12701270
static bool shouldSkipChecking(const ValueDecl *VD) {
1271-
if (VD->getFormalAccess() != AccessLevel::Internal)
1271+
if (VD->getFormalAccess() != AccessLevel::Internal &&
1272+
VD->getFormalAccess() != AccessLevel::Package)
12721273
return true;
12731274
return !VD->isUsableFromInline();
12741275
};

Diff for: lib/Sema/TypeCheckAttr.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -2886,8 +2886,9 @@ void AttributeChecker::visitUsableFromInlineAttr(UsableFromInlineAttr *attr) {
28862886
return;
28872887
}
28882888

2889-
// @usableFromInline can only be applied to internal declarations.
2890-
if (VD->getFormalAccess() != AccessLevel::Internal) {
2889+
// @usableFromInline can only be applied to internal or package declarations.
2890+
if (VD->getFormalAccess() != AccessLevel::Internal &&
2891+
VD->getFormalAccess() != AccessLevel::Package) {
28912892
diagnoseAndRemoveAttr(attr,
28922893
diag::usable_from_inline_attr_with_explicit_access,
28932894
VD->getName(), VD->getFormalAccess());

Diff for: test/AutoDiff/Sema/derivative_attr_type_checking.swift

+79-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s
2-
// RUN: %target-swift-frontend-typecheck -enable-testing -verify -disable-availability-checking %s
1+
// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s -package-name myPkg
2+
// RUN: %target-swift-frontend-typecheck -enable-testing -verify -disable-availability-checking %s -package-name myPkg
33

44
// Swift.AdditiveArithmetic:3:17: note: cannot yet register derivative default implementation for protocol requirements
55

@@ -1001,6 +1001,12 @@ func _public_original_usablefrominline_derivative(_ x: Float) -> (value: Float,
10011001
fatalError()
10021002
}
10031003

1004+
package func package_original_package_derivative(_ x: Float) -> Float { x }
1005+
@derivative(of: package_original_package_derivative)
1006+
package func _package_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1007+
fatalError()
1008+
}
1009+
10041010
func internal_original_internal_derivative(_ x: Float) -> Float { x }
10051011
@derivative(of: internal_original_internal_derivative)
10061012
func _internal_original_internal_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
@@ -1040,6 +1046,28 @@ func _internal_original_alwaysemitintoclient_derivative(_ x: Float) -> (value: F
10401046
fatalError()
10411047
}
10421048

1049+
1050+
package func package_original_usablefrominline_derivative(_ x: Float) -> Float { x }
1051+
@usableFromInline
1052+
@derivative(of: package_original_usablefrominline_derivative)
1053+
package func _package_original_usablefrominline_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1054+
fatalError()
1055+
}
1056+
1057+
package func package_original_inlinable_derivative(_ x: Float) -> Float { x }
1058+
@inlinable
1059+
@derivative(of: package_original_inlinable_derivative)
1060+
package func _package_original_inlinable_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1061+
fatalError()
1062+
}
1063+
1064+
package func package_original_alwaysemitintoclient_derivative(_ x: Float) -> Float { x }
1065+
@_alwaysEmitIntoClient
1066+
@derivative(of: package_original_alwaysemitintoclient_derivative)
1067+
package func _package_original_alwaysemitintoclient_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1068+
fatalError()
1069+
}
1070+
10431071
// MARK: - Original function visibility < derivative function visibility
10441072

10451073
@usableFromInline
@@ -1051,6 +1079,23 @@ public func _usablefrominline_original_public_derivative(_ x: Float) -> (value:
10511079
fatalError()
10521080
}
10531081

1082+
@usableFromInline
1083+
package func package_usablefrominline_original_public_derivative(_ x: Float) -> Float { x }
1084+
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_package__usablefrominline_original_public_derivative' is public, but original function 'package_usablefrominline_original_public_derivative' is package}}
1085+
@derivative(of: package_usablefrominline_original_public_derivative)
1086+
// expected-note @+1 {{mark the derivative function as 'package' to match the original function}} {{1-7=package}}
1087+
public func _package__usablefrominline_original_public_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1088+
fatalError()
1089+
}
1090+
1091+
package func package_original_public_derivative(_ x: Float) -> Float { x }
1092+
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_package_original_public_derivative' is public, but original function 'package_original_public_derivative' is package}}
1093+
@derivative(of: package_original_public_derivative)
1094+
// expected-note @+1 {{mark the derivative function as 'package' to match the original function}} {{1-7=package}}
1095+
public func _package_original_public_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1096+
fatalError()
1097+
}
1098+
10541099
func internal_original_public_derivative(_ x: Float) -> Float { x }
10551100
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_internal_original_public_derivative' is public, but original function 'internal_original_public_derivative' is internal}}
10561101
@derivative(of: internal_original_public_derivative)
@@ -1059,6 +1104,14 @@ public func _internal_original_public_derivative(_ x: Float) -> (value: Float, p
10591104
fatalError()
10601105
}
10611106

1107+
func internal_original_package_derivative(_ x: Float) -> Float { x }
1108+
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_internal_original_package_derivative' is package, but original function 'internal_original_package_derivative' is internal}}
1109+
@derivative(of: internal_original_package_derivative)
1110+
// expected-note @+1 {{mark the derivative function as 'internal' to match the original function}} {{1-8=internal}}
1111+
package func _internal_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1112+
fatalError()
1113+
}
1114+
10621115
private func private_original_usablefrominline_derivative(_ x: Float) -> Float { x }
10631116
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_private_original_usablefrominline_derivative' is internal, but original function 'private_original_usablefrominline_derivative' is private}}
10641117
@derivative(of: private_original_usablefrominline_derivative)
@@ -1076,6 +1129,14 @@ public func _private_original_public_derivative(_ x: Float) -> (value: Float, pu
10761129
fatalError()
10771130
}
10781131

1132+
private func private_original_package_derivative(_ x: Float) -> Float { x }
1133+
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_private_original_package_derivative' is package, but original function 'private_original_package_derivative' is private}}
1134+
@derivative(of: private_original_package_derivative)
1135+
// expected-note @+1 {{mark the derivative function as 'private' to match the original function}}
1136+
package func _private_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1137+
fatalError()
1138+
}
1139+
10791140
private func private_original_internal_derivative(_ x: Float) -> Float { x }
10801141
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_private_original_internal_derivative' is internal, but original function 'private_original_internal_derivative' is private}}
10811142
@derivative(of: private_original_internal_derivative)
@@ -1110,6 +1171,14 @@ fileprivate func _public_original_private_derivative(_ x: Float) -> (value: Floa
11101171
fatalError()
11111172
}
11121173

1174+
public func public_original_package_derivative(_ x: Float) -> Float { x }
1175+
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_public_original_package_derivative' is package, but original function 'public_original_package_derivative' is public}}
1176+
@derivative(of: public_original_package_derivative)
1177+
package func _public_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1178+
// expected-note @-1 {{mark the derivative function as '@usableFromInline' to match the original function}} {{-1:1-1=@usableFromInline }}
1179+
fatalError()
1180+
}
1181+
11131182
public func public_original_internal_derivative(_ x: Float) -> Float { x }
11141183
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_public_original_internal_derivative' is internal, but original function 'public_original_internal_derivative' is public}}
11151184
@derivative(of: public_original_internal_derivative)
@@ -1118,6 +1187,14 @@ func _public_original_internal_derivative(_ x: Float) -> (value: Float, pullback
11181187
fatalError()
11191188
}
11201189

1190+
package func package_original_internal_derivative(_ x: Float) -> Float { x }
1191+
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_package_original_internal_derivative' is internal, but original function 'package_original_internal_derivative' is package}}
1192+
@derivative(of: package_original_internal_derivative)
1193+
// expected-note @+1 {{mark the derivative function as 'package' to match the original function}} {{1-1=package }}
1194+
func _package_original_internal_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
1195+
fatalError()
1196+
}
1197+
11211198
func internal_original_fileprivate_derivative(_ x: Float) -> Float { x }
11221199
// expected-error @+1 {{derivative function must have same access level as original function; derivative function '_internal_original_fileprivate_derivative' is fileprivate, but original function 'internal_original_fileprivate_derivative' is internal}}
11231200
@derivative(of: internal_original_fileprivate_derivative)

Diff for: test/Compatibility/attr_usableFromInline_swift4.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4 -disable-objc-attr-requires-foundation-module -enable-objc-interop
33

44
@usableFromInline private func privateVersioned() {}
5-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}}
5+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'privateVersioned()' is private}}
66

77
@usableFromInline fileprivate func fileprivateVersioned() {}
8-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'fileprivateVersioned()' is fileprivate}}
8+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'fileprivateVersioned()' is fileprivate}}
99

1010
@usableFromInline internal func internalVersioned() {}
1111
// OK
@@ -14,11 +14,11 @@
1414
// OK
1515

1616
@usableFromInline public func publicVersioned() {}
17-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}}
17+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}}
1818

1919
internal class InternalClass {
2020
@usableFromInline public func publicVersioned() {}
21-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}}
21+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}}
2222
}
2323

2424
fileprivate class filePrivateClass {

Diff for: test/Compatibility/attr_usableFromInline_swift42.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4.2 -disable-objc-attr-requires-foundation-module -enable-objc-interop
33

44
@usableFromInline private func privateVersioned() {}
5-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}}
5+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'privateVersioned()' is private}}
66

77
@usableFromInline fileprivate func fileprivateVersioned() {}
8-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'fileprivateVersioned()' is fileprivate}}
8+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'fileprivateVersioned()' is fileprivate}}
99

1010
@usableFromInline internal func internalVersioned() {}
1111
// OK
@@ -14,12 +14,12 @@
1414
// OK
1515

1616
@usableFromInline public func publicVersioned() {}
17-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}}
17+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}}
1818

1919
internal class InternalClass {
2020
// expected-note@-1 2{{type declared here}}
2121
@usableFromInline public func publicVersioned() {}
22-
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}}
22+
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}}
2323
}
2424

2525
fileprivate class filePrivateClass {
@@ -119,7 +119,7 @@ where T : InternalProtocol,
119119

120120
@usableFromInline
121121
protocol BadProtocol : InternalProtocol {
122-
// expected-warning@-1 {{protocol refined by '@usableFromInline' protocol should be '@usableForInline' or public}}
122+
// expected-warning@-1 {{protocol refined by '@usableFromInline' protocol should be '@usableFromInline' or public}}
123123
associatedtype X : InternalProtocol
124124
// expected-warning@-1 {{type referenced from a requirement of an associated type in a '@usableFromInline' protocol should be '@usableFromInline' or public}}
125125
associatedtype Y = InternalStruct
@@ -128,7 +128,7 @@ protocol BadProtocol : InternalProtocol {
128128

129129
@usableFromInline
130130
protocol AnotherBadProtocol where Self.T : InternalProtocol {
131-
// expected-warning@-1 {{protocol used by '@usableFromInline' protocol should be '@usableForInline' or public}}
131+
// expected-warning@-1 {{protocol used by '@usableFromInline' protocol should be '@usableFromInline' or public}}
132132
associatedtype T
133133
}
134134

Diff for: test/SPI/local_spi_decls.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Checks for SPI declarations and limited exportability.
22

33
// RUN: %empty-directory(%t)
4-
// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -enable-library-evolution -swift-version 5
4+
// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -enable-library-evolution -swift-version 5 -package-name myPkg
55

66
// Without -enable-library-evolution the exportability check looks at struct internal properties.
7-
// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -swift-version 5
7+
// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -swift-version 5 -package-name myPkg
88

99
// SPI declarations
1010
@_spi(MySPI) public func spiFunc() {}
@@ -120,3 +120,7 @@ public func inlinableSPI() {
120120
spiFunc()
121121
let _ = SPIClass()
122122
}
123+
124+
@_spi(S) func internalFunc() {} // expected-error {{internal global function cannot be declared '@_spi' because only public and open declarations can be '@_spi'}}
125+
126+
@_spi(S) package func packageFunc() {} // expected-error {{package global function cannot be declared '@_spi' because only public and open declarations can be '@_spi'}}

0 commit comments

Comments
 (0)