mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Allow @frozen and @_fixed_layout for package access level.
Package decls were made to be resilient at the definition site by default. By allowing the attributes to be applied to package decls, we can enable non-resilient access. Resolves rdar://125169361
This commit is contained in:
@@ -6794,18 +6794,18 @@ WARNING(discardable_result_on_void_never_function, none,
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
ERROR(fixed_layout_attr_on_internal_type,
|
||||
none, "'@_fixed_layout' attribute can only be applied to '@usableFromInline' "
|
||||
"or public declarations, but %0 is "
|
||||
"%select{private|fileprivate|internal|package|%error|%error}1",
|
||||
none, "'@_fixed_layout' attribute can only be applied to '@usableFromInline', "
|
||||
"package, or public declarations, but %0 is "
|
||||
"%select{private|fileprivate|internal|%error|%error|%error}1",
|
||||
(DeclName, AccessLevel))
|
||||
|
||||
WARNING(fixed_layout_struct,
|
||||
none, "'@frozen' attribute is now used for fixed-layout structs", ())
|
||||
|
||||
ERROR(frozen_attr_on_internal_type,
|
||||
none, "'@frozen' attribute can only be applied to '@usableFromInline' "
|
||||
"or public declarations, but %0 is "
|
||||
"%select{private|fileprivate|internal|package|%error|%error}1",
|
||||
none, "'@frozen' attribute can only be applied to '@usableFromInline', "
|
||||
"package, or public declarations, but %0 is "
|
||||
"%select{private|fileprivate|internal|%error|%error|%error}1",
|
||||
(DeclName, AccessLevel))
|
||||
|
||||
ERROR(usable_from_inline_attr_with_explicit_access,
|
||||
@@ -6897,8 +6897,8 @@ ERROR(inlinable_dynamic_not_supported,
|
||||
none, "'@inlinable' attribute cannot be applied to 'dynamic' declarations", ())
|
||||
|
||||
ERROR(inlinable_decl_not_public,
|
||||
none, "'@inlinable' attribute can only be applied to public declarations, "
|
||||
"but %0 is %select{private|fileprivate|internal|package|%error|%error}1",
|
||||
none, "'@inlinable' attribute can only be applied to package or public declarations, "
|
||||
"but %0 is %select{private|fileprivate|internal|%error|%error|%error}1",
|
||||
(DeclBaseName, AccessLevel))
|
||||
|
||||
ERROR(inlinable_resilient_deinit,
|
||||
|
||||
@@ -3168,7 +3168,7 @@ void AttributeChecker::visitFixedLayoutAttr(FixedLayoutAttr *attr) {
|
||||
|
||||
auto *VD = cast<ValueDecl>(D);
|
||||
|
||||
if (VD->getFormalAccess() < AccessLevel::Public &&
|
||||
if (VD->getFormalAccess() < AccessLevel::Package &&
|
||||
!VD->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
|
||||
diagnoseAndRemoveAttr(attr, diag::fixed_layout_attr_on_internal_type,
|
||||
VD->getName(), VD->getFormalAccess());
|
||||
@@ -3227,7 +3227,8 @@ void AttributeChecker::visitInlinableAttr(InlinableAttr *attr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// @inlinable can only be applied to public or internal declarations.
|
||||
// @inlinable can only be applied to public, package, or
|
||||
// internal declarations.
|
||||
auto access = VD->getFormalAccess();
|
||||
if (access < AccessLevel::Internal) {
|
||||
diagnoseAndRemoveAttr(attr, diag::inlinable_decl_not_public,
|
||||
@@ -3934,7 +3935,7 @@ void AttributeChecker::visitFrozenAttr(FrozenAttr *attr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ED->getFormalAccess() < AccessLevel::Public &&
|
||||
if (ED->getFormalAccess() < AccessLevel::Package &&
|
||||
!ED->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
|
||||
diagnoseAndRemoveAttr(attr, diag::enum_frozen_nonpublic, attr);
|
||||
return;
|
||||
@@ -3943,7 +3944,9 @@ void AttributeChecker::visitFrozenAttr(FrozenAttr *attr) {
|
||||
|
||||
auto *VD = cast<ValueDecl>(D);
|
||||
|
||||
if (VD->getFormalAccess() < AccessLevel::Public &&
|
||||
// @frozen attribute is allowed for public, package, or
|
||||
// usableFromInline decls.
|
||||
if (VD->getFormalAccess() < AccessLevel::Package &&
|
||||
!VD->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
|
||||
diagnoseAndRemoveAttr(attr, diag::frozen_attr_on_internal_type,
|
||||
VD->getName(), VD->getFormalAccess());
|
||||
|
||||
44
test/Sema/package_frozen_fixed_layout.swift
Normal file
44
test/Sema/package_frozen_fixed_layout.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
// RUN: %target-swift-frontend -typecheck %s -I %t -swift-version 5 -package-name mypkg -verify
|
||||
|
||||
package struct PkgStruct {
|
||||
package var one: Int
|
||||
package var two: String
|
||||
package func f() {}
|
||||
}
|
||||
|
||||
@frozen
|
||||
package struct FrozenPkgStruct {
|
||||
package var one: Int
|
||||
package var two: String
|
||||
package func f() {}
|
||||
}
|
||||
|
||||
@frozen
|
||||
@usableFromInline
|
||||
package struct FrozenUfiPkgStruct {
|
||||
package var one: Int
|
||||
package var two: String
|
||||
package func f() {}
|
||||
}
|
||||
|
||||
@frozen // expected-error {{'@frozen' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FrozenInternalStruct' is internal}} {{1-9=}}
|
||||
struct FrozenInternalStruct {
|
||||
var one: Int
|
||||
var two: String
|
||||
func f() {}
|
||||
}
|
||||
|
||||
@_fixed_layout
|
||||
package class FixedPkgKlass {
|
||||
package var one: Int = 1
|
||||
package var two: String = ""
|
||||
package func f() {}
|
||||
}
|
||||
|
||||
@_fixed_layout // expected-error {{'@_fixed_layout' attribute can only be applied to '@usableFromInline', package, or public declarations, but 'FixedInternalKlass' is internal}} {{1-16=}}
|
||||
class FixedInternalKlass {
|
||||
var one: Int = 1
|
||||
var two: String = ""
|
||||
func f() {}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
// RUN: -experimental-allow-non-resilient-access \
|
||||
// RUN: -emit-module -emit-module-path %t/Utils.swiftmodule
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %t/Utils.swift -I %t -swift-version 5 -package-name mypkg -verify
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %t/ClientDefault.swift -I %t -swift-version 5 -package-name mypkg -verify
|
||||
|
||||
// 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 {
|
||||
case two(Int)
|
||||
}
|
||||
|
||||
@frozen
|
||||
package enum FrozenPkgEnum {
|
||||
case one
|
||||
case two(Int)
|
||||
}
|
||||
|
||||
@frozen
|
||||
@usableFromInline
|
||||
package enum FrozenUfiPkgEnum {
|
||||
case one
|
||||
case two(Int)
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
package enum UfiPkgEnum {
|
||||
case one
|
||||
@@ -36,6 +51,61 @@ public enum FrozenPublicEnum {
|
||||
case two(Int)
|
||||
}
|
||||
|
||||
package func uf(_ arg: PkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
package func um(_ arg: FrozenPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
package func un(_ arg: FrozenUfiPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
package func ug(_ arg: UfiPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
public func uh(_ arg: PublicEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
public func uk(_ arg: FrozenPublicEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- ClientDefault.swift
|
||||
import Utils
|
||||
|
||||
@@ -48,6 +118,24 @@ package func f(_ arg: PkgEnum) -> Int {
|
||||
}
|
||||
}
|
||||
|
||||
package func m(_ arg: FrozenPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
package func n(_ arg: FrozenUfiPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
package func g(_ arg: UfiPkgEnum) -> Int {
|
||||
switch arg { // expected-warning {{switch covers known cases, but 'UfiPkgEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
|
||||
case .one:
|
||||
@@ -80,8 +168,8 @@ public func k(_ arg: FrozenPublicEnum) -> Int {
|
||||
import Utils
|
||||
|
||||
// With optimization enabled to bypass resilience checks within
|
||||
// a package boundary, public (non-frozen) or package enums no
|
||||
// longer require `@unknown default` in source code switch stmts.
|
||||
// a package boundary, public (non-frozen) or package (non-frozen)
|
||||
// enums no longer require `@unknown default` in switch stmts.
|
||||
package func f(_ arg: PkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
@@ -91,6 +179,24 @@ package func f(_ arg: PkgEnum) -> Int {
|
||||
}
|
||||
}
|
||||
|
||||
package func m(_ arg: FrozenPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
package func n(_ arg: FrozenUfiPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
return 1
|
||||
case .two(let val):
|
||||
return 2 + val
|
||||
}
|
||||
}
|
||||
|
||||
package func g(_ arg: UfiPkgEnum) -> Int {
|
||||
switch arg { // no-warning
|
||||
case .one:
|
||||
|
||||
Reference in New Issue
Block a user