diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index f589e6062d647..08151fb6e404f 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2439,10 +2439,10 @@ WARNING(protocol_access_warn,none, (bool, AccessLevel, bool, AccessLevel, bool, DescriptiveDeclKind)) ERROR(protocol_usable_from_inline,none, "protocol %select{refined|used}0 by '@usableFromInline' protocol " - "must be '@usableForInline' or public", (bool)) + "must be '@usableFromInline' or public", (bool)) WARNING(protocol_usable_from_inline_warn,none, "protocol %select{refined|used}0 by '@usableFromInline' protocol " - "should be '@usableForInline' or public", (bool)) + "should be '@usableFromInline' or public", (bool)) ERROR(protocol_property_must_be_computed_var,none, "protocols cannot require properties to be immutable; declare read-only " "properties by using 'var' with a '{ get }' specifier", ()) @@ -6162,7 +6162,7 @@ ERROR(frozen_attr_on_internal_type, (DeclName, AccessLevel)) ERROR(usable_from_inline_attr_with_explicit_access, - none, "'@usableFromInline' attribute can only be applied to internal " + none, "'@usableFromInline' attribute can only be applied to internal or package " "declarations, but %0 is %select{private|fileprivate|%error|package|public|open}1", (DeclName, AccessLevel)) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c5d2a7bf90111..705ba4ee484b7 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3646,7 +3646,7 @@ SourceLoc ValueDecl::getAttributeInsertionLoc(bool forModifier) const { /// Returns true if \p VD needs to be treated as publicly-accessible /// at the SIL, LLVM, and machine levels due to being @usableFromInline. bool ValueDecl::isUsableFromInline() const { - assert(getFormalAccess() <= AccessLevel::Internal); + assert(getFormalAccess() < AccessLevel::Public); if (getAttrs().hasAttribute() || getAttrs().hasAttribute() || @@ -3767,7 +3767,7 @@ static AccessLevel getAdjustedFormalAccess(const ValueDecl *VD, return getMaximallyOpenAccessFor(VD); if (treatUsableFromInlineAsPublic && - access <= AccessLevel::Internal && + access < AccessLevel::Public && VD->isUsableFromInline()) { return AccessLevel::Public; } @@ -4073,8 +4073,9 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD, // marked 'public' if the protocol was '@_versioned' (now // '@usableFromInline'). Which works at the ABI level, so let's keep // supporting that here by explicitly checking for it. + auto protoAccess = proto->getFormalAccess(); if (access == AccessLevel::Public && - proto->getFormalAccess() == AccessLevel::Internal && + (protoAccess == AccessLevel::Internal || protoAccess == AccessLevel::Package) && proto->isUsableFromInline()) { return true; } diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index a9ed46578d7ec..9fe55f63548d9 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -1268,7 +1268,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase, : AccessControlCheckerBase(/*checkUsableFromInline=*/true) {} static bool shouldSkipChecking(const ValueDecl *VD) { - if (VD->getFormalAccess() != AccessLevel::Internal) + if (VD->getFormalAccess() != AccessLevel::Internal && + VD->getFormalAccess() != AccessLevel::Package) return true; return !VD->isUsableFromInline(); }; diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 14e5469be422b..dd4fdc8ee09cd 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -2886,8 +2886,9 @@ void AttributeChecker::visitUsableFromInlineAttr(UsableFromInlineAttr *attr) { return; } - // @usableFromInline can only be applied to internal declarations. - if (VD->getFormalAccess() != AccessLevel::Internal) { + // @usableFromInline can only be applied to internal or package declarations. + if (VD->getFormalAccess() != AccessLevel::Internal && + VD->getFormalAccess() != AccessLevel::Package) { diagnoseAndRemoveAttr(attr, diag::usable_from_inline_attr_with_explicit_access, VD->getName(), VD->getFormalAccess()); diff --git a/test/AutoDiff/Sema/derivative_attr_type_checking.swift b/test/AutoDiff/Sema/derivative_attr_type_checking.swift index aa9c00b4cb2ce..9b4bc05592c90 100644 --- a/test/AutoDiff/Sema/derivative_attr_type_checking.swift +++ b/test/AutoDiff/Sema/derivative_attr_type_checking.swift @@ -1,5 +1,5 @@ -// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s -// RUN: %target-swift-frontend-typecheck -enable-testing -verify -disable-availability-checking %s +// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s -package-name myPkg +// RUN: %target-swift-frontend-typecheck -enable-testing -verify -disable-availability-checking %s -package-name myPkg // Swift.AdditiveArithmetic:3:17: note: cannot yet register derivative default implementation for protocol requirements @@ -1001,6 +1001,12 @@ func _public_original_usablefrominline_derivative(_ x: Float) -> (value: Float, fatalError() } +package func package_original_package_derivative(_ x: Float) -> Float { x } +@derivative(of: package_original_package_derivative) +package func _package_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + func internal_original_internal_derivative(_ x: Float) -> Float { x } @derivative(of: internal_original_internal_derivative) 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 fatalError() } + +package func package_original_usablefrominline_derivative(_ x: Float) -> Float { x } +@usableFromInline +@derivative(of: package_original_usablefrominline_derivative) +package func _package_original_usablefrominline_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + +package func package_original_inlinable_derivative(_ x: Float) -> Float { x } +@inlinable +@derivative(of: package_original_inlinable_derivative) +package func _package_original_inlinable_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + +package func package_original_alwaysemitintoclient_derivative(_ x: Float) -> Float { x } +@_alwaysEmitIntoClient +@derivative(of: package_original_alwaysemitintoclient_derivative) +package func _package_original_alwaysemitintoclient_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + // MARK: - Original function visibility < derivative function visibility @usableFromInline @@ -1051,6 +1079,23 @@ public func _usablefrominline_original_public_derivative(_ x: Float) -> (value: fatalError() } +@usableFromInline +package func package_usablefrominline_original_public_derivative(_ x: Float) -> Float { x } +// 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}} +@derivative(of: package_usablefrominline_original_public_derivative) +// expected-note @+1 {{mark the derivative function as 'package' to match the original function}} {{1-7=package}} +public func _package__usablefrominline_original_public_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + +package func package_original_public_derivative(_ x: Float) -> Float { x } +// 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}} +@derivative(of: package_original_public_derivative) +// expected-note @+1 {{mark the derivative function as 'package' to match the original function}} {{1-7=package}} +public func _package_original_public_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + func internal_original_public_derivative(_ x: Float) -> Float { x } // 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}} @derivative(of: internal_original_public_derivative) @@ -1059,6 +1104,14 @@ public func _internal_original_public_derivative(_ x: Float) -> (value: Float, p fatalError() } +func internal_original_package_derivative(_ x: Float) -> Float { x } +// 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}} +@derivative(of: internal_original_package_derivative) +// expected-note @+1 {{mark the derivative function as 'internal' to match the original function}} {{1-8=internal}} +package func _internal_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + private func private_original_usablefrominline_derivative(_ x: Float) -> Float { x } // 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}} @derivative(of: private_original_usablefrominline_derivative) @@ -1076,6 +1129,14 @@ public func _private_original_public_derivative(_ x: Float) -> (value: Float, pu fatalError() } +private func private_original_package_derivative(_ x: Float) -> Float { x } +// 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}} +@derivative(of: private_original_package_derivative) +// expected-note @+1 {{mark the derivative function as 'private' to match the original function}} +package func _private_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + private func private_original_internal_derivative(_ x: Float) -> Float { x } // 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}} @derivative(of: private_original_internal_derivative) @@ -1110,6 +1171,14 @@ fileprivate func _public_original_private_derivative(_ x: Float) -> (value: Floa fatalError() } +public func public_original_package_derivative(_ x: Float) -> Float { x } +// 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}} +@derivative(of: public_original_package_derivative) +package func _public_original_package_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + // expected-note @-1 {{mark the derivative function as '@usableFromInline' to match the original function}} {{-1:1-1=@usableFromInline }} + fatalError() +} + public func public_original_internal_derivative(_ x: Float) -> Float { x } // 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}} @derivative(of: public_original_internal_derivative) @@ -1118,6 +1187,14 @@ func _public_original_internal_derivative(_ x: Float) -> (value: Float, pullback fatalError() } +package func package_original_internal_derivative(_ x: Float) -> Float { x } +// 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}} +@derivative(of: package_original_internal_derivative) +// expected-note @+1 {{mark the derivative function as 'package' to match the original function}} {{1-1=package }} +func _package_original_internal_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} + func internal_original_fileprivate_derivative(_ x: Float) -> Float { x } // 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}} @derivative(of: internal_original_fileprivate_derivative) diff --git a/test/Compatibility/attr_usableFromInline_swift4.swift b/test/Compatibility/attr_usableFromInline_swift4.swift index 32ae83fc20ff6..b050642a8a1d3 100644 --- a/test/Compatibility/attr_usableFromInline_swift4.swift +++ b/test/Compatibility/attr_usableFromInline_swift4.swift @@ -2,10 +2,10 @@ // RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4 -disable-objc-attr-requires-foundation-module -enable-objc-interop @usableFromInline private func privateVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'privateVersioned()' is private}} @usableFromInline fileprivate func fileprivateVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'fileprivateVersioned()' is fileprivate}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'fileprivateVersioned()' is fileprivate}} @usableFromInline internal func internalVersioned() {} // OK @@ -14,11 +14,11 @@ // OK @usableFromInline public func publicVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}} internal class InternalClass { @usableFromInline public func publicVersioned() {} - // expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}} + // expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}} } fileprivate class filePrivateClass { diff --git a/test/Compatibility/attr_usableFromInline_swift42.swift b/test/Compatibility/attr_usableFromInline_swift42.swift index 61fd7a0406b09..2c2dad82eb1d8 100644 --- a/test/Compatibility/attr_usableFromInline_swift42.swift +++ b/test/Compatibility/attr_usableFromInline_swift42.swift @@ -2,10 +2,10 @@ // RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4.2 -disable-objc-attr-requires-foundation-module -enable-objc-interop @usableFromInline private func privateVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'privateVersioned()' is private}} @usableFromInline fileprivate func fileprivateVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'fileprivateVersioned()' is fileprivate}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'fileprivateVersioned()' is fileprivate}} @usableFromInline internal func internalVersioned() {} // OK @@ -14,12 +14,12 @@ // OK @usableFromInline public func publicVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}} internal class InternalClass { // expected-note@-1 2{{type declared here}} @usableFromInline public func publicVersioned() {} - // expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}} + // expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}} } fileprivate class filePrivateClass { @@ -119,7 +119,7 @@ where T : InternalProtocol, @usableFromInline protocol BadProtocol : InternalProtocol { - // expected-warning@-1 {{protocol refined by '@usableFromInline' protocol should be '@usableForInline' or public}} + // expected-warning@-1 {{protocol refined by '@usableFromInline' protocol should be '@usableFromInline' or public}} associatedtype X : InternalProtocol // expected-warning@-1 {{type referenced from a requirement of an associated type in a '@usableFromInline' protocol should be '@usableFromInline' or public}} associatedtype Y = InternalStruct @@ -128,7 +128,7 @@ protocol BadProtocol : InternalProtocol { @usableFromInline protocol AnotherBadProtocol where Self.T : InternalProtocol { - // expected-warning@-1 {{protocol used by '@usableFromInline' protocol should be '@usableForInline' or public}} + // expected-warning@-1 {{protocol used by '@usableFromInline' protocol should be '@usableFromInline' or public}} associatedtype T } diff --git a/test/SPI/local_spi_decls.swift b/test/SPI/local_spi_decls.swift index 6c531611de5a1..12fb61e39a580 100644 --- a/test/SPI/local_spi_decls.swift +++ b/test/SPI/local_spi_decls.swift @@ -1,10 +1,10 @@ // Checks for SPI declarations and limited exportability. // RUN: %empty-directory(%t) -// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -enable-library-evolution -swift-version 5 +// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -enable-library-evolution -swift-version 5 -package-name myPkg // Without -enable-library-evolution the exportability check looks at struct internal properties. -// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -swift-version 5 +// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -swift-version 5 -package-name myPkg // SPI declarations @_spi(MySPI) public func spiFunc() {} @@ -120,3 +120,7 @@ public func inlinableSPI() { spiFunc() let _ = SPIClass() } + +@_spi(S) func internalFunc() {} // expected-error {{internal global function cannot be declared '@_spi' because only public and open declarations can be '@_spi'}} + +@_spi(S) package func packageFunc() {} // expected-error {{package global function cannot be declared '@_spi' because only public and open declarations can be '@_spi'}} diff --git a/test/Sema/accessibility_package.swift b/test/Sema/accessibility_package.swift index 8cc75b0b26d7d..fa42ce168538b 100644 --- a/test/Sema/accessibility_package.swift +++ b/test/Sema/accessibility_package.swift @@ -4,45 +4,116 @@ // RUN: %target-swift-frontend -module-name Utils %t/Utils.swift -emit-module -emit-module-path %t/Utils.swiftmodule -package-name myLib // RUN: test -f %t/Utils.swiftmodule -// RUN: %target-swift-frontend -module-name Lib %t/Lib.swift -emit-module -emit-module-path %t/Lib.swiftmodule -package-name myLib -I %t -// RUN: test -f %t/Lib.swiftmodule +// RUN: %target-swift-frontend -module-name LibGood %t/LibGood.swift -emit-module -emit-module-path %t/LibGood.swiftmodule -package-name myLib -I %t +// RUN: test -f %t/LibGood.swiftmodule -// RUN: not %target-swift-frontend -typecheck %t/Lib.swift -package-name "otherLib" -I %t 2>&1 | %FileCheck %s -// CHECK: error: cannot find type 'PackageProto' in scope -// CHECK: error: 'pkgFunc' is inaccessible due to 'package' protection level -// CHECK: error: cannot find 'PackageKlass' in scope +// 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 +// RUN: %FileCheck %s -input-file %t/resultClient.output -check-prefix CHECK-CLIENT +// CHECK-CLIENT: error: 'pkgVar' is inaccessible due to 'package' protection level +// CHECK-CLIENT: error: 'pkgFunc' is inaccessible due to 'package' protection level + +// RUN: not %target-swift-frontend -typecheck %t/Lib.swift -package-name myLib -I %t 2> %t/result1.output +// RUN: %FileCheck %s -input-file %t/result1.output -check-prefix CHECK-1 +// CHECK-1: error: overriding non-open instance method outside of its defining module +// CHECK-1: error: overriding non-open instance method outside of its defining module +// CHECK-1: error: cannot inherit from non-open class 'PublicKlass' outside of its defining module +// CHECK-1: error: cannot inherit from non-open class 'PackageKlass' outside of its defining module +// CHECK-1: error: cannot assign to property: 'publicGetInternal' setter is inaccessible +// CHECK-1: error: cannot assign to property: 'pkgVar' setter is inaccessible + +// RUN: not %target-swift-frontend -typecheck %t/Lib.swift -package-name "otherLib" -I %t 2> %t/result2.output +// %FileCheck %s -input-file %t/result2.output -check-prefix CHECK-2 +// CHECK-2: error: cannot find type 'PackageProto' in scope +// CHECK-2: error: 'pkgFunc' is inaccessible due to 'package' protection level +// CHECK-2: error: cannot find 'PackageKlass' in scope // BEGIN Utils.swift package protocol PackageProto { - var pkgVar: String { get set } + var pkgVar: Double { get set } + func pkgFunc() } package class PackageKlass { package init() {} + package private(set) var pkgVar: Double = 1.0 package func pkgFunc() {} } +class InternalKlass {} + public class PublicKlass { public init() {} + public var publicVar: Int = 1 + public package(set) var publicGetPkg: Int = 2 + public internal(set) var publicGetInternal: Int = 3 public func publicFunc() {} package func pkgFunc() {} } +open class OpenKlass { + public init() {} + open var openVar: String = "" + open func openFunc() {} + public func publicFunc() {} + package func packageFunc() {} +} // BEGIN Lib.swift import Utils -public func start() { +// Test accessing public and package decls +public func test() { let x = PublicKlass() x.publicFunc() - x.pkgFunc() + x.pkgFunc() // Allowed if in same package + x.publicGetPkg = 3 // Allowed if in same package + x.publicGetInternal = 4 // Not allowed + + let y = PackageKlass() // Allowed if in same package + y.pkgVar = 1.5 // Not allowed + y.pkgFunc() // Allowed if in same package +} + +// Test conformance to a package protocol +package struct LibStruct : PackageProto { // Allowed if in same package + package var pkgVar: Double = 1.0 + package func pkgFunc() {} +} - let y = PackageKlass() - y.pkgFunc() +// Test subclassing / overrides +class SubOpenKlass: OpenKlass { + override open func openFunc() {} + override public func publicFunc() {} + override package func packageFunc() {} } +class SubPublicKlass: PublicKlass {} // Not allowed +class SubPackageKlass: PackageKlass {} // Not allowed -package struct LibStruct : PackageProto { - package var pkgVar: String = "lib" + + +// BEGIN LibGood.swift +import Utils + +public func libFunc() { + _ = LibStruct() } +public struct LibStruct: PackageProto { + public init() {} + package var pkgVar: Double = 1.0 + package func pkgFunc() {} + public var publicVar: String = "" + public func publicFunc() {} +} + +// BEGIN Client.swift +import LibGood + +func clientFunc() { + let lib = LibStruct() + _ = lib.pkgVar // Not allowed + _ = lib.publicVar + lib.pkgFunc() // Not allowed + lib.publicFunc() +} diff --git a/test/Sema/accessibility_package_inline.swift b/test/Sema/accessibility_package_inline.swift new file mode 100644 index 0000000000000..f9e407e844f1b --- /dev/null +++ b/test/Sema/accessibility_package_inline.swift @@ -0,0 +1,180 @@ +// RUN: %empty-directory(%t) +// RUN: %{python} %utils/split_file.py -o %t %s + +// RUN: %target-swift-frontend -module-name UtilsGood %t/UtilsGood.swift -emit-module -emit-module-path %t/UtilsGood.swiftmodule -package-name myLib +// RUN: test -f %t/UtilsGood.swiftmodule + +// RUN: not %target-swift-frontend -typecheck %t/Utils.swift -package-name myLib -I %t 2> %t/resultUtils.output +// RUN: %FileCheck %s -input-file %t/resultUtils.output -check-prefix CHECK-UTILS +// CHECK-UTILS: error: class 'PackageKlass' is package and cannot be referenced from an '@inlinable' function +// CHECK-UTILS: let a = PackageKlass() +// CHECK-UTILS: ^ +// CHECK-UTILS: note: class 'PackageKlass' is not '@usableFromInline' or public +// CHECK-UTILS: package class PackageKlass { +// CHECK-UTILS: ^ +// CHECK-UTILS: error: initializer 'init()' is package and cannot be referenced from an '@inlinable' function +// CHECK-UTILS: let a = PackageKlass() // should error +// CHECK-UTILS: ^ +// CHECK-UTILS: note: initializer 'init()' is not '@usableFromInline' or public +// CHECK-UTILS: package init() {} +// CHECK-UTILS: ^ +// CHECK-UTILS: error: class 'InternalKlass' is internal and cannot be referenced from an '@inlinable' function +// CHECK-UTILS: let b = InternalKlass() // should error +// CHECK-UTILS: ^ +// CHECK-UTILS: note: class 'InternalKlass' is not '@usableFromInline' or public +// CHECK-UTILS: class InternalKlass { +// CHECK-UTILS: ^ +// CHECK-UTILS: error: initializer 'init()' is internal and cannot be referenced from an '@inlinable' function +// CHECK-UTILS: let b = InternalKlass() // should error +// CHECK-UTILS: ^ +// CHECK-UTILS: note: initializer 'init()' is not '@usableFromInline' or public +// CHECK-UTILS: init() {} +// CHECK-UTILS: ^ + +// RUN: not %target-swift-frontend -typecheck %t/Lib.swift -package-name "otherLib" -I %t 2> %t/resultLib.output +// %FileCheck %s -input-file %t/resultLib.output -check-prefix CHECK-LIB +// CHECK-LIB: error: cannot find 'packageFunc' in scope +// CHECK-LIB: packageFunc() +// CHECK-LIB: ^~~~~~~~~~~ + +// RUN: %target-swift-frontend -module-name Lib %t/Lib.swift -emit-module -emit-module-path %t/Lib.swiftmodule -package-name myLib -I %t +// RUN: test -f %t/Lib.swiftmodule + +// BEGIN Utils.swift +package protocol PackageProto { + var pkgVar: Double { get set } + func pkgFunc() +} + +package class PackageKlass { + package init() {} + package private(set) var pkgVar: Double = 1.0 + package func pkgFunc() {} +} + +@usableFromInline +package class PackageKlassProto: PackageProto { + @usableFromInline + package init() {} + @usableFromInline + package var pkgVar = 1.0 + package func pkgFunc() {} +} + +@usableFromInline +package class PackageKlassForInline { + @usableFromInline + package init() {} +} + +protocol InternalProto { + var internalVar: Double { get set } + func internalFunc() +} +class InternalKlass { + init() {} +} +@usableFromInline +class InternalKlassProto: InternalProto { + @usableFromInline + init() {} + var internalVar = 1.0 + func internalFunc() {} +} + +@usableFromInline +class InternalKlassForInline { + @usableFromInline + init() {} +} + +@inlinable +public func publicFunc() { + let a = PackageKlass() // should error + let b = InternalKlass() // should error + let c = PackageKlassProto() + let d = InternalKlassProto() + let e = PackageKlassForInline() + let f = InternalKlassForInline() + print(a, b, c, d, e, f) +} + +@inlinable +func internalFunc() { + let a = PackageKlass() // should error + let b = InternalKlass() // should error + let c = PackageKlassProto() + let d = InternalKlassProto() + let e = PackageKlassForInline() + let f = InternalKlassForInline() + print(a, b, c, d, e, f) +} + +@inlinable +package func packageFunc() { + let a = PackageKlass() // should error + let b = InternalKlass() // should error + let c = PackageKlassProto() + let d = InternalKlassProto() + let e = PackageKlassForInline() + let f = InternalKlassForInline() + print(a, b, c, d, e, f) +} + +// BEGIN UtilsGood.swift +package protocol PackageProto { + var pkgVar: Double { get set } + func pkgFunc() +} + +package class PackageKlass { + package init() {} + package private(set) var pkgVar: Double = 1.0 + package func pkgFunc() {} +} + +@usableFromInline +package class PackageKlassForInline { + @usableFromInline + package init() {} +} + +class InternalKlass { + init() {} +} + +@usableFromInline +class InternalKlassForInline { + @usableFromInline + init() {} +} + +@inlinable +public func publicFunc() { + let x = PackageKlassForInline() + let y = InternalKlassForInline() + print(x, y) +} + +@inlinable +func internalFunc() { + let x = PackageKlassForInline() + let y = InternalKlassForInline() + print(x, y) +} + +@inlinable +package func packageFunc() { + let x = PackageKlassForInline() + let y = InternalKlassForInline() + print(x, y) +} + +// BEGIN Lib.swift +import UtilsGood + +@inlinable +public func libFunc() { + publicFunc() + packageFunc() // Allowed if in same package +} diff --git a/test/Sema/accessibility_package_inline_interface.swift b/test/Sema/accessibility_package_inline_interface.swift new file mode 100644 index 0000000000000..e7fb933a4327e --- /dev/null +++ b/test/Sema/accessibility_package_inline_interface.swift @@ -0,0 +1,145 @@ +// RUN: %empty-directory(%t) +// RUN: %{python} %utils/split_file.py -o %t %s + +// RUN: %target-swift-frontend -module-name Utils1 %t/Utils.swift -emit-module -emit-module-path %t/Utils1.swiftmodule -package-name myLib -swift-version 5 +// RUN: test -f %t/Utils1.swiftmodule + +// RUN: %target-swift-frontend -module-name Utils %t/Utils.swift -emit-module -emit-module-interface-path %t/Utils.swiftinterface -package-name myLib -enable-library-evolution -swift-version 5 +// RUN: test -f %t/Utils.swiftinterface +// RUN: %target-swift-typecheck-module-from-interface(%t/Utils.swiftinterface) -I%t + +// RUN: %FileCheck %s -check-prefix CHECK-UTILS < %t/Utils.swiftinterface +// CHECK-UTILS: -module-name Utils -enable-library-evolution +// CHECK-UTILS: swift-module-flags-ignorable: -package-name myLib +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: package class PackageKlassProto { +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: package init() +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: package var pkgVar: Swift.Double +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: deinit +// CHECK-UTILS: } +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: package class PackageKlassForInline { +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: package init() +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: package func foo1() +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: deinit +// CHECK-UTILS: } +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: internal class InternalKlassProto { +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: internal init() +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: internal var internalVar: Swift.Double +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: deinit +// CHECK-UTILS: } +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: internal class InternalKlassForInline { +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: internal init() +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: internal func bar1() +// CHECK-UTILS: @usableFromInline +// CHECK-UTILS: deinit +// CHECK-UTILS: } +// CHECK-UTILS: @inlinable public func publicFunc() { +// CHECK-UTILS: let a = PackageKlassProto().pkgVar +// CHECK-UTILS: let b = InternalKlassProto().internalVar +// CHECK-UTILS: PackageKlassForInline().foo1() +// CHECK-UTILS: InternalKlassForInline().bar1() +// CHECK-UTILS: print(a, b) +// CHECK-UTILS: } +// CHECK-UTILS: @inlinable internal func internalFunc() { +// CHECK-UTILS: let a = PackageKlassProto().pkgVar +// CHECK-UTILS: let b = InternalKlassProto().internalVar +// CHECK-UTILS: PackageKlassForInline().foo1() +// CHECK-UTILS: InternalKlassForInline().bar1() +// CHECK-UTILS: print(a, b) +// CHECK-UTILS: } +// CHECK-UTILS: @inlinable package func packageFunc() { +// CHECK-UTILS: let a = PackageKlassProto().pkgVar +// CHECK-UTILS: let b = InternalKlassProto().internalVar +// CHECK-UTILS: PackageKlassForInline().foo1() +// CHECK-UTILS: InternalKlassForInline().bar1() +// CHECK-UTILS: print(a, b) +// CHECK-UTILS: } + + +// BEGIN Utils.swift +package protocol PackageProto { + var pkgVar: Double { get set } + func pkgFunc() +} + +package class PackageKlass { + package init() {} + package private(set) var pkgVar: Double = 1.0 + package func pkgFunc() {} +} + +@usableFromInline +package class PackageKlassProto: PackageProto { + @usableFromInline package init() {} + @usableFromInline package var pkgVar = 1.0 + package func pkgFunc() {} +} + +@usableFromInline +package class PackageKlassForInline { + @usableFromInline package init() {} + @usableFromInline package func foo1() {} + package func foo2() {} +} + +protocol InternalProto { + var internalVar: Double { get set } + func internalFunc() +} +class InternalKlass { + init() {} +} +@usableFromInline +class InternalKlassProto: InternalProto { + @usableFromInline init() {} + @usableFromInline var internalVar = 1.0 + func internalFunc() {} +} + +@usableFromInline +class InternalKlassForInline { + @usableFromInline init() {} + @usableFromInline func bar1() {} + func bar2() {} +} + +@inlinable +public func publicFunc() { + let a = PackageKlassProto().pkgVar + let b = InternalKlassProto().internalVar + PackageKlassForInline().foo1() + InternalKlassForInline().bar1() + print(a, b) +} + +@inlinable +func internalFunc() { + let a = PackageKlassProto().pkgVar + let b = InternalKlassProto().internalVar + PackageKlassForInline().foo1() + InternalKlassForInline().bar1() + print(a, b) +} + +@inlinable +package func packageFunc() { + let a = PackageKlassProto().pkgVar + let b = InternalKlassProto().internalVar + PackageKlassForInline().foo1() + InternalKlassForInline().bar1() + print(a, b) +} diff --git a/test/Sema/property_wrapper_parameter_invalid.swift b/test/Sema/property_wrapper_parameter_invalid.swift index 7bae8576c8785..53cd619220fa9 100644 --- a/test/Sema/property_wrapper_parameter_invalid.swift +++ b/test/Sema/property_wrapper_parameter_invalid.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -swift-version 5 +// RUN: %target-typecheck-verify-swift -swift-version 5 -package-name myPkg @propertyWrapper struct NonMutatingWrapper { @@ -140,6 +140,15 @@ public struct PublicWrapper { public var projectedValue: PublicWrapper { self } } +// expected-note@+2 2 {{generic struct 'PackageWrapper' is not '@usableFromInline' or public}} +@propertyWrapper +package struct PackageWrapper { // expected-note 3 {{type declared here}} + package var wrappedValue: T + + // expected-note@+1 2 {{initializer 'init(wrappedValue:)' is not '@usableFromInline' or public}} + package init(wrappedValue: T) { self.wrappedValue = wrappedValue } +} + // expected-note@+2 2 {{generic struct 'InternalWrapper' is not '@usableFromInline' or public}} @propertyWrapper struct InternalWrapper { // expected-note 3 {{type declared here}} @@ -167,6 +176,18 @@ public func testComposition2(@InternalWrapper @PublicWrapper value: Int) {} // Okay because `InternalWrapper` is implementation-detail. @usableFromInline func testComposition4(@InternalWrapper @PublicWrapper value: Int) {} +// expected-error@+1 {{function cannot be declared public because its parameter uses a package API wrapper type}} +public func testComposition1pkg(@PublicWrapper @PackageWrapper value: Int) {} + +// Okay because `PackageWrapper` is implementation-detail. +public func testComposition2pkg(@PackageWrapper @PublicWrapper value: Int) {} + +// expected-error@+1 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}} +@usableFromInline func testComposition3pkg(@PublicWrapper @PackageWrapper value: Int) {} + +// Okay because `PackageWrapper` is implementation-detail. +@usableFromInline func testComposition4pkg(@PackageWrapper @PublicWrapper value: Int) {} + // expected-error@+3 {{generic struct 'InternalWrapper' is internal and cannot be referenced from an '@inlinable' function}} // expected-error@+2 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}} // expected-error@+1 {{initializer 'init(wrappedValue:)' is internal and cannot be referenced from an '@inlinable' function}} @@ -176,6 +197,15 @@ public func testComposition2(@InternalWrapper @PublicWrapper value: Int) {} // expected-error@+1 {{initializer 'init(wrappedValue:)' is internal and cannot be referenced from an '@inlinable' function}} @inlinable func testComposition6(@InternalWrapper @PublicWrapper value: Int) {} +// expected-error@+3 {{generic struct 'PackageWrapper' is package and cannot be referenced from an '@inlinable' function}} +// expected-error@+2 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}} +// expected-error@+1 {{initializer 'init(wrappedValue:)' is package and cannot be referenced from an '@inlinable' function}} +@inlinable func testComposition5pkg(@PublicWrapper @PackageWrapper value: Int) {} + +// expected-error@+2 {{generic struct 'PackageWrapper' is package and cannot be referenced from an '@inlinable' function}} +// expected-error@+1 {{initializer 'init(wrappedValue:)' is package and cannot be referenced from an '@inlinable' function}} +@inlinable func testComposition6pkg(@PackageWrapper @PublicWrapper value: Int) {} + protocol Q { associatedtype A } diff --git a/test/attr/accessibility_proto.swift b/test/attr/accessibility_proto.swift index cd4e06a7873da..78fe2d4a83484 100644 --- a/test/attr/accessibility_proto.swift +++ b/test/attr/accessibility_proto.swift @@ -1,3 +1,4 @@ +// RUN: %target-typecheck-verify-swift -package-name myPkg // RUN: %target-swift-frontend -typecheck -disable-access-control -package-name myPkg %s public protocol ProtoWithReqs { @@ -27,7 +28,7 @@ public extension Adopter2 { internal typealias AssocA = Int // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-12=}} package typealias AssocB = String - // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-12=}} + // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-11=}} fileprivate func foo() {} // expected-note@-1 {{mark the instance method as 'public' to satisfy the requirement}} {{3-15=}} } @@ -51,10 +52,11 @@ public struct Adopter4 : ProtoWithReqs {} // expected-error@-3 {{type alias 'AssocB' must be declared public because it matches a requirement in public protocol 'ProtoWithReqs'}} {{none}} package extension Adopter4 { internal typealias AssocA = Int - // expected-note@-1 {{mark the type alias as 'package' to satisfy the requirement}} {{3-12=}} - typealias AssocB = String // package modifier is redundant for package extension + // expected-note@-1 {{move the type alias to another extension where it can be declared 'public' to satisfy the requirement}} {{none}} + typealias AssocB = String + // expected-note@-1 {{move the type alias to another extension where it can be declared 'public' to satisfy the requirement}} {{none}} fileprivate func foo() {} - // expected-note@-1 {{mark the instance method as 'package' to satisfy the requirement}} {{3-15=}} + // expected-note@-1 {{move the instance method to another extension where it can be declared 'public' to satisfy the requirement}} {{none}} } @@ -65,9 +67,9 @@ package protocol PkgProtoWithReqs { } package struct Adopter5 : PkgProtoWithReqs {} -// expected-error@-1 {{method 'foo()' must be declared public because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} -// expected-error@-2 {{type alias 'AssocA' must be declared public because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} -// expected-error@-3 {{type alias 'AssocB' must be declared public because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} +// expected-error@-1 {{method 'foo()' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} +// expected-error@-2 {{type alias 'AssocA' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} +// expected-error@-3 {{type alias 'AssocB' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} extension Adopter5 { typealias AssocA = Int // expected-note@-1 {{mark the type alias as 'package' to satisfy the requirement}} {{3-3=package }} @@ -81,7 +83,7 @@ public class AnotherAdopterBase { typealias AssocA = Int // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-3=public }} package typealias AssocB = String - // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-11=public }} + // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-10=public}} func foo() {} // expected-note@-1 {{mark the instance method as 'public' to satisfy the requirement}} {{3-3=public }} } @@ -152,7 +154,7 @@ extension ReqProvider { func foo() {} // expected-note@-1 {{mark the instance method as 'public' to satisfy the requirement}} {{3-3=public }} package typealias AssocB = String - // expected-note@-1 {{mark the instance method as 'public' to satisfy the requirement}} {{3-11=public }} + // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-10=public}} } public struct AdoptViaProtocol : ProtoWithReqs, ReqProvider { // expected-error@-1 {{method 'foo()' must be declared public because it matches a requirement in public protocol 'ProtoWithReqs'}} {{none}} @@ -160,17 +162,23 @@ public struct AdoptViaProtocol : ProtoWithReqs, ReqProvider { public typealias AssocA = Int } -package protocol PkgReqProvider {} -extension PkgReqProvider { - private func foo() {} - // expected-note@-1 {{mark the instance method as 'package' to satisfy the requirement}} {{3-11=public }} - typealias AssocB = String - // expected-note@-1 {{mark the instance method as 'package' to satisfy the requirement}} {{3-3=public }} +internal protocol InternalProtoWithReqs { + associatedtype AssocA // expected-note * {{type declared here}} + associatedtype AssocB // expected-note * {{type declared here}} + func foo() } -package struct PkgAdoptViaProtocol : PkgProtoWithReqs, PkgReqProvider { - // expected-error@-1 {{method 'foo()' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} - // expected-error@-2 {{type alias 'AssocB' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} - package typealias AssocA = Int + +internal protocol InternalReqProvider {} +extension InternalReqProvider { + fileprivate func foo() {} + // expected-note@-1 {{mark the instance method as 'internal' to satisfy the requirement}} {{3-14=internal}} + fileprivate typealias AssocB = String + // expected-note@-1 {{mark the type alias as 'internal' to satisfy the requirement}} {{3-14=internal}} +} +internal struct InternalAdoptViaProtocol : InternalProtoWithReqs, InternalReqProvider { + // expected-error@-1 {{method 'foo()' must be declared internal because it matches a requirement in internal protocol 'InternalProtoWithReqs'}} {{none}} + // expected-error@-2 {{type alias 'AssocB' must be declared internal because it matches a requirement in internal protocol 'InternalProtoWithReqs'}} {{none}} + internal typealias AssocA = Int } public protocol ReqProvider2 {} @@ -178,24 +186,11 @@ extension ProtoWithReqs where Self : ReqProvider2 { func foo() {} // expected-note@-1 {{mark the instance method as 'public' to satisfy the requirement}} {{3-3=public }} typealias AssocB = String - // expected-note@-1 {{mark the instance method as 'public' to satisfy the requirement}} {{3-3=public }} + // expected-note@-1 {{mark the type alias as 'public' to satisfy the requirement}} {{3-3=public }} } public struct AdoptViaCombinedProtocol : ProtoWithReqs, ReqProvider2 { // expected-error@-1 {{method 'foo()' must be declared public because it matches a requirement in public protocol 'ProtoWithReqs'}} {{none}} - // expected-error@-2 {{type alias 'AssocB' must be declared public because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} - public typealias AssocA = Int -} - -package protocol PkgReqProvider2 {} -extension PkgProtoWithReqs where Self : PkgReqProvider2 { - func foo() {} - // expected-note@-1 {{mark the instance method as 'package' to satisfy the requirement}} {{3-3=public }} - typealias AssocB = String - // expected-note@-1 {{mark the instance method as 'package' to satisfy the requirement}} {{3-3=public }} -} -package struct PkgAdoptViaCombinedProtocol : PkgProtoWithReqs, PkgReqProvider2 { - // expected-error@-1 {{method 'foo()' must be declared public because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} - // expected-error@-2 {{type alias 'AssocB' must be declared package because it matches a requirement in package protocol 'PkgProtoWithReqs'}} {{none}} + // expected-error@-2 {{type alias 'AssocB' must be declared public because it matches a requirement in public protocol 'ProtoWithReqs'}} {{none}} public typealias AssocA = Int } @@ -216,7 +211,6 @@ public struct NonPublicMemberwiseInitStruct: PublicInitProto { public var value: Int } - package protocol PackageInitProto { var value: Int { get } init(value: Int) @@ -247,5 +241,5 @@ package protocol PkgEmptyInit { init() } public struct PkgBuggy: PkgEmptyInit { - // expected-error@-1 {{initializer 'init()' must be declared public because it matches a requirement in package protocol 'PkgEmptyInit'}} + // expected-error@-1 {{initializer 'init()' must be declared package because it matches a requirement in package protocol 'PkgEmptyInit'}} } diff --git a/test/attr/attr_fixed_layout_property_wrapper.swift b/test/attr/attr_fixed_layout_property_wrapper.swift index a2b4417e1da00..643e207837e4e 100644 --- a/test/attr/attr_fixed_layout_property_wrapper.swift +++ b/test/attr/attr_fixed_layout_property_wrapper.swift @@ -1,9 +1,22 @@ -// RUN: %target-typecheck-verify-swift -swift-version 5 +// RUN: %target-typecheck-verify-swift -swift-version 5 -package-name myPkg private class PrivateType {} // expected-note {{class 'PrivateType' is not '@usableFromInline' or public}} // expected-note@-1 {{initializer 'init()' is not '@usableFromInline' or public}} // expected-note@-2 {{type declared here}} +package class PackageType { + // expected-note@-1 {{class 'PackageType' is not '@usableFromInline' or public}} + // expected-note@-2 {{type declared here}} + package init() {} + // expected-note@-1 {{initializer 'init()' is not '@usableFromInline' or public}} +} + +@usableFromInline +package class PackageTypeForInline { + @usableFromInline + package init() {} +} + @propertyWrapper public struct Wrapper { public init(wrappedValue: T) {} @@ -19,4 +32,15 @@ public struct Wrapper { // expected-error@-1 {{class 'PrivateType' is private and cannot be referenced from a property initializer in a '@frozen' type}} // expected-error@-2 {{initializer 'init()' is private and cannot be referenced from a property initializer in a '@frozen' type}} // expected-error@-3 {{type referenced from a stored property with inferred type 'PrivateType' in a '@frozen' struct must be '@usableFromInline' or public}} + + @Wrapper private var x1: PackageType + // expected-error@-1 {{type referenced from a stored property in a '@frozen' struct must be '@usableFromInline' or public}} + + @Wrapper private var x2 = PackageType() + // expected-error@-1 {{class 'PackageType' is package and cannot be referenced from a property initializer in a '@frozen' type}} + // expected-error@-2 {{initializer 'init()' is package and cannot be referenced from a property initializer in a '@frozen' type}} + // expected-error@-3 {{type referenced from a stored property with inferred type 'PackageType' in a '@frozen' struct must be '@usableFromInline' or public}} + + @Wrapper private var z1: PackageTypeForInline + @Wrapper private var z2 = PackageTypeForInline() } diff --git a/test/attr/attr_usableFromInline.swift b/test/attr/attr_usableFromInline.swift index 7211b028d868f..fee5f53dce614 100644 --- a/test/attr/attr_usableFromInline.swift +++ b/test/attr/attr_usableFromInline.swift @@ -1,29 +1,72 @@ -// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-objc-attr-requires-foundation-module -enable-objc-interop -// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-objc-attr-requires-foundation-module -enable-objc-interop -enable-testing +// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-objc-attr-requires-foundation-module -enable-objc-interop -package-name myPkg +// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-objc-attr-requires-foundation-module -enable-objc-interop -enable-testing -package-name myPkg @usableFromInline private func privateVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'privateVersioned()' is private}} @usableFromInline fileprivate func fileprivateVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'fileprivateVersioned()' is fileprivate}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'fileprivateVersioned()' is fileprivate}} @usableFromInline internal func internalVersioned() {} // OK +@usableFromInline package func packageVersioned() {} +// OK + @usableFromInline func implicitInternalVersioned() {} // OK @usableFromInline public func publicVersioned() {} -// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}} +// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}} + +// expected-note@+1 3{{global function 'internalFunc()' is not '@usableFromInline' or public}} +internal func internalFunc() {} +// expected-note@+1 3{{global function 'packageFunc()' is not '@usableFromInline' or public}} +package func packageFunc() {} +public func publicFunc() {} + +@inlinable +public func publicInlinableFunc() { + internalVersioned() // OK + internalFunc() // expected-error {{global function 'internalFunc()' is internal and cannot be referenced from an '@inlinable' function}} + packageVersioned() // OK + packageFunc() // expected-error {{global function 'packageFunc()' is package and cannot be referenced from an '@inlinable' function}} + publicFunc() // OK +} + +@inlinable +func internalInlinableFunc() { + internalVersioned() // OK + internalFunc() // expected-error {{global function 'internalFunc()' is internal and cannot be referenced from an '@inlinable' function}} + packageVersioned() // OK + packageFunc() // expected-error {{global function 'packageFunc()' is package and cannot be referenced from an '@inlinable' function}} + publicFunc() // OK +} + +@inlinable +package func packageInlinableFunc() { + internalVersioned() // OK + internalFunc() // expected-error {{global function 'internalFunc()' is internal and cannot be referenced from an '@inlinable' function}} + packageVersioned() // OK + packageFunc() // expected-error {{global function 'packageFunc()' is package and cannot be referenced from an '@inlinable' function}} + publicFunc() // OK +} + +package class PackageClass { + // expected-note@-1 *{{type declared here}} + @usableFromInline public func publicVersioned() {} + // expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}} +} internal class InternalClass { // expected-note@-1 2{{type declared here}} @usableFromInline public func publicVersioned() {} - // expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'publicVersioned()' is public}} + // expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal or package declarations, but 'publicVersioned()' is public}} } fileprivate class filePrivateClass { @usableFromInline internal func internalVersioned() {} + @usableFromInline package func packageVersioned() {} } @usableFromInline struct S { @@ -34,6 +77,15 @@ fileprivate class filePrivateClass { @usableFromInline extension S {} // expected-error@-1 {{'@usableFromInline' attribute cannot be applied to this declaration}} +@usableFromInline package struct Pkg { + var x: Int + @usableFromInline var y: Int + @usableFromInline package var z: Int +} + +@usableFromInline extension Pkg {} +// expected-error@-1 {{'@usableFromInline' attribute cannot be applied to this declaration}} + @usableFromInline protocol VersionedProtocol { associatedtype T @@ -48,16 +100,38 @@ protocol VersionedProtocol { // expected-error@-1 {{'@usableFromInline' attribute cannot be used in protocols}} } +@usableFromInline +package protocol PkgVersionedProtocol { + associatedtype T + + func requirement() -> T + + public func publicRequirement() -> T + // expected-error@-1 {{'public' modifier cannot be used in protocols}} + // expected-note@-2 {{protocol requirements implicitly have the same access as the protocol itself}} + + @usableFromInline func versionedRequirement() -> T + // expected-error@-1 {{'@usableFromInline' attribute cannot be used in protocols}} +} + // Derived conformances had issues with @usableFromInline - rdar://problem/34342955 @usableFromInline internal enum EqEnum { case foo } +@usableFromInline +package enum PkgEqEnum { + case foo +} @usableFromInline internal enum RawEnum : Int { case foo = 0 } +@usableFromInline +package enum PkgRawEnum : Int { + case foo = 0 +} @inlinable public func usesEqEnum() -> Bool { @@ -66,12 +140,21 @@ public func usesEqEnum() -> Bool { _ = RawEnum.foo.rawValue _ = RawEnum(rawValue: 0) + + _ = (PkgEqEnum.foo == .foo) + _ = PkgEqEnum.foo.hashValue + + _ = PkgRawEnum.foo.rawValue + _ = PkgRawEnum(rawValue: 0) } public class DynamicMembers { @usableFromInline @objc dynamic init() {} @usableFromInline @objc dynamic func foo() {} @usableFromInline @objc dynamic var bar: Int = 0 + @usableFromInline @objc dynamic package init(arg: Int) {} + @usableFromInline @objc dynamic package func baz() {} + @usableFromInline @objc dynamic package var cat: Int = 0 } internal struct InternalStruct {} @@ -86,6 +169,19 @@ internal struct InternalStruct {} @usableFromInline typealias BadAlias = InternalStruct // expected-error@-1 {{type referenced from the underlying type of a '@usableFromInline' type alias must be '@usableFromInline' or public}} +package struct PackageStruct {} +// expected-note@-1 *{{type declared here}} + +@usableFromInline var globalInferredPkg = PackageStruct() +// expected-error@-1 {{type referenced from a '@usableFromInline' variable with inferred type 'PackageStruct' must be '@usableFromInline' or public}} + +@usableFromInline var globalDeclaredPkg: PackageStruct = PackageStruct() +// expected-error@-1 {{type referenced from a '@usableFromInline' variable must be '@usableFromInline' or public}} + +@usableFromInline typealias BadAliasPkg = PackageStruct +// expected-error@-1 {{type referenced from the underlying type of a '@usableFromInline' type alias must be '@usableFromInline' or public}} + + protocol InternalProtocol { // expected-note@-1 * {{type declared here}} associatedtype T @@ -125,7 +221,7 @@ where T : InternalProtocol, @usableFromInline protocol BadProtocol : InternalProtocol { - // expected-error@-1 {{protocol refined by '@usableFromInline' protocol must be '@usableForInline' or public}} + // expected-error@-1 {{protocol refined by '@usableFromInline' protocol must be '@usableFromInline' or public}} associatedtype X : InternalProtocol // expected-error@-1 {{type referenced from a requirement of an associated type in a '@usableFromInline' protocol must be '@usableFromInline' or public}} associatedtype Y = InternalStruct @@ -134,32 +230,107 @@ protocol BadProtocol : InternalProtocol { @usableFromInline protocol AnotherBadProtocol where Self.T : InternalProtocol { - // expected-error@-1 {{protocol used by '@usableFromInline' protocol must be '@usableForInline' or public}} + // expected-error@-1 {{protocol used by '@usableFromInline' protocol must be '@usableFromInline' or public}} + associatedtype T +} + + +package protocol PackageProtocol { + // expected-note@-1 * {{type declared here}} associatedtype T } +@usableFromInline +package struct PkgBadStruct +// expected-error@-1 {{type referenced from a generic requirement of a '@usableFromInline' generic struct must be '@usableFromInline' or public}} +where T : PackageProtocol, + T : Sequence, + T.Element == PackageStruct { + @usableFromInline init(x: PackageStruct) {} + // expected-error@-1 {{the parameter of a '@usableFromInline' initializer must be '@usableFromInline' or public}} + + @usableFromInline func foo(x: PackageStruct) -> PackageClass {} + // expected-error@-1 {{the parameter of a '@usableFromInline' method must be '@usableFromInline' or public}} + // expected-error@-2 {{the result of a '@usableFromInline' method must be '@usableFromInline' or public}} + + @usableFromInline var propertyInferred = PackageStruct() + // expected-error@-1 {{type referenced from a '@usableFromInline' property with inferred type 'PackageStruct' must be '@usableFromInline' or public}} + + @usableFromInline var propertyDeclared: PackageStruct = PackageStruct() + // expected-error@-1 {{type referenced from a '@usableFromInline' property must be '@usableFromInline' or public}} + + @usableFromInline subscript(x: PackageStruct) -> Int { + // expected-error@-1 {{index type of a '@usableFromInline' subscript must be '@usableFromInline' or public}} + get {} + set {} + } + + @usableFromInline subscript(x: Int) -> PackageStruct { + // expected-error@-1 {{element type of a '@usableFromInline' subscript must be '@usableFromInline' or public}} + get {} + set {} + } +} + +@usableFromInline +package protocol PkgBadProtocol : PackageProtocol { + // expected-error@-1 {{protocol refined by '@usableFromInline' protocol must be '@usableFromInline' or public}} + associatedtype X : PackageProtocol + // expected-error@-1 {{type referenced from a requirement of an associated type in a '@usableFromInline' protocol must be '@usableFromInline' or public}} + associatedtype Y = PackageProtocol + // expected-error@-1 {{type referenced from a default definition of an associated type in a '@usableFromInline' protocol must be '@usableFromInline' or public}} +} + +@usableFromInline +package protocol PkgAnotherBadProtocol where Self.T : PackageProtocol { + // expected-error@-1 {{protocol used by '@usableFromInline' protocol must be '@usableFromInline' or public}} + associatedtype T +} + + @usableFromInline enum BadEnum { case bad(InternalStruct) // expected-error@-1 {{type of enum case in '@usableFromInline' enum must be '@usableFromInline' or public}} } +@usableFromInline +package enum PkgBadEnum { + case bad(PackageStruct) + // expected-error@-1 {{type of enum case in '@usableFromInline' enum must be '@usableFromInline' or public}} +} + @usableFromInline class BadClass : InternalClass {} // expected-error@-1 {{type referenced from the superclass of a '@usableFromInline' class must be '@usableFromInline' or public}} +@usableFromInline +package class PkgBadClass : PackageClass {} +// expected-error@-1 {{type referenced from the superclass of a '@usableFromInline' class must be '@usableFromInline' or public}} + public struct TestGenericSubscripts { @usableFromInline subscript(_: T) -> Int { return 0 } // expected-warning {{type referenced from a generic parameter of a '@usableFromInline' subscript should be '@usableFromInline' or public}} @usableFromInline subscript(where _: T) -> Int where T: InternalProtocol { return 0 } // expected-warning {{type referenced from a generic requirement of a '@usableFromInline' subscript should be '@usableFromInline' or public}} + @usableFromInline package subscript(_: T) -> Int { return 0 } // expected-warning {{type referenced from a generic parameter of a '@usableFromInline' subscript should be '@usableFromInline' or public}} + @usableFromInline package subscript(where _: T) -> Int where T: PackageProtocol { return 0 } // expected-warning {{type referenced from a generic requirement of a '@usableFromInline' subscript should be '@usableFromInline' or public}} } @usableFromInline typealias TestGenericAlias = T // expected-warning {{type referenced from a generic parameter of a '@usableFromInline' type alias should be '@usableFromInline' or public}} @usableFromInline typealias TestGenericAliasWhereClause = T where T: InternalProtocol // expected-warning {{type referenced from a generic requirement of a '@usableFromInline' type alias should be '@usableFromInline' or public}} +@usableFromInline typealias PkgTestGenericAlias = T // expected-warning {{type referenced from a generic parameter of a '@usableFromInline' type alias should be '@usableFromInline' or public}} +@usableFromInline typealias PkgTestGenericAliasWhereClause = T where T: PackageProtocol // expected-warning {{type referenced from a generic requirement of a '@usableFromInline' type alias should be '@usableFromInline' or public}} + @usableFromInline struct GenericStruct { @usableFromInline struct Nested where T : InternalProtocol {} // expected-error@-1 {{type referenced from a generic requirement of a '@usableFromInline' struct must be '@usableFromInline' or public}} @usableFromInline func nonGenericWhereClause() where T : InternalProtocol {} // expected-error@-1 {{type referenced from a generic requirement of a '@usableFromInline' instance method must be '@usableFromInline' or public}} + + @usableFromInline package struct PkgNested where T : PackageProtocol {} + // expected-error@-1 {{type referenced from a generic requirement of a '@usableFromInline' struct must be '@usableFromInline' or public}} + + @usableFromInline package func pkgNonGenericWhereClause() where T : PackageProtocol {} + // expected-error@-1 {{type referenced from a generic requirement of a '@usableFromInline' instance method must be '@usableFromInline' or public}} } diff --git a/test/decl/protocol/conforms/access_corner_case.swift b/test/decl/protocol/conforms/access_corner_case.swift index f5aef4b939e86..e786086d4a19d 100644 --- a/test/decl/protocol/conforms/access_corner_case.swift +++ b/test/decl/protocol/conforms/access_corner_case.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -package-name myPkg // Protocol requirement is witnessed from a member of a @@ -7,6 +7,10 @@ public protocol P { func publicRequirement() } +package protocol Pkg: P { + func packageRequirement() +} + protocol Q : P { func internalRequirement() } @@ -31,10 +35,36 @@ extension S { private func privateRequirementCannotWork() {} } - public struct T : S {} // expected-error@-1 {{type 'T' does not conform to protocol 'S'}} +protocol Qpkg : Pkg { + func internalRequirement() +} + +fileprivate protocol Rpkg : Qpkg { + func fileprivateRequirement() +} +private protocol Spkg : Rpkg { + func privateRequirement() + func privateRequirementCannotWork() + // expected-note@-1 {{protocol requires function 'privateRequirementCannotWork()' with type '() -> ()'; do you want to add a stub?}} +} + +extension Spkg { + public func publicRequirement() {} + package func packageRequirement() {} + internal func internalRequirement() {} + fileprivate func fileprivateRequirement() {} + fileprivate func privateRequirement() {} + + // Cannot witness requirement in another protocol! + private func privateRequirementCannotWork() {} +} + +public struct Tpkg : Spkg {} +// expected-error@-1 {{type 'Tpkg' does not conform to protocol 'Spkg'}} + // This is also OK @usableFromInline internal protocol U : P {} @@ -45,6 +75,16 @@ extension U { public struct SS : U {} +@usableFromInline +package protocol Upkg : P {} + +extension Upkg { + public func publicRequirement() {} +} + +public struct SSpkg : Upkg {} + + // Currently this is banned public protocol P2 { func publicRequirement() @@ -59,3 +99,13 @@ extension Q2 { } public struct T2 : Q2 {} // expected-error {{method 'publicRequirement()' must be declared public because it matches a requirement in public protocol 'P2'}} + +package protocol Q2pkg : P2 {} + +extension Q2pkg { + // note: not public + func publicRequirement() {} + // expected-note@-1 {{mark the instance method as 'public' to satisfy the requirement}} {{3-3=public }} +} + +public struct T2pkg : Q2pkg {} // expected-error {{method 'publicRequirement()' must be declared public because it matches a requirement in public protocol 'P2'}} diff --git a/test/decl/protocol/special/coding/class_codable_member_type_lookup.swift b/test/decl/protocol/special/coding/class_codable_member_type_lookup.swift index 5a39556e34de3..a5aff44830681 100644 --- a/test/decl/protocol/special/coding/class_codable_member_type_lookup.swift +++ b/test/decl/protocol/special/coding/class_codable_member_type_lookup.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -verify-ignore-unknown +// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -package-name myPkg // A top-level CodingKeys type to fall back to in lookups below. public enum CodingKeys : String, CodingKey { @@ -17,6 +17,7 @@ struct SynthesizedClass : Codable { // Qualified type lookup should always be unambiguous. public func qualifiedFoo(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared public because its parameter uses a private type}} + package func qualifiedPkg(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared package because its parameter uses a private type}} internal func qualifiedBar(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared internal because its parameter uses a private type}} fileprivate func qualifiedBaz(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared fileprivate because its parameter uses a private type}} private func qualifiedQux(_ key: SynthesizedClass.CodingKeys) {} @@ -27,6 +28,10 @@ struct SynthesizedClass : Codable { print(CodingKeys.value) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + print(CodingKeys.value) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} print(CodingKeys.value) // Not found on top-level. } @@ -53,6 +58,19 @@ struct SynthesizedClass : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} enum CodingKeys : String, CodingKey { case nested @@ -96,6 +114,7 @@ struct SynthesizedClass : Codable { struct Nested { // Qualified lookup should remain as-is. public func qualifiedFoo(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared public because its parameter uses a private type}} + package func qualifiedPkg(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared package because its parameter uses a private type}} internal func qualifiedBar(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared internal because its parameter uses a private type}} fileprivate func qualifiedBaz(_ key: SynthesizedClass.CodingKeys) {} // expected-error {{method cannot be declared fileprivate because its parameter uses a private type}} private func qualifiedQux(_ key: SynthesizedClass.CodingKeys) {} @@ -106,6 +125,10 @@ struct SynthesizedClass : Codable { print(CodingKeys.value) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + print(CodingKeys.value) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} print(CodingKeys.value) // Not found on top-level. } @@ -132,6 +155,19 @@ struct SynthesizedClass : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} enum CodingKeys : String, CodingKey { case nested @@ -177,7 +213,7 @@ struct SynthesizedClass : Codable { // Classes which don't get synthesized Codable implementations should expose the // appropriate CodingKeys type. -struct NonSynthesizedClass : Codable { // expected-note 4 {{'NonSynthesizedClass' declared here}} +struct NonSynthesizedClass : Codable { // expected-note * {{'NonSynthesizedClass' declared here}} // No synthesized type since we implemented both methods. init(from decoder: Decoder) throws {} func encode(to encoder: Encoder) throws {} @@ -185,12 +221,14 @@ struct NonSynthesizedClass : Codable { // expected-note 4 {{'NonSynthesizedClass // Qualified type lookup should clearly fail -- we shouldn't get a synthesized // type here. public func qualifiedFoo(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}} + package func qualifiedPkg(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}} internal func qualifiedBar(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}} fileprivate func qualifiedBaz(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}} private func qualifiedQux(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}} // Unqualified lookups should find the public top-level CodingKeys type. public func unqualifiedFoo(_ key: CodingKeys) { print(CodingKeys.topLevel) } + package func unqualifiedPkg(_ key: CodingKeys) { print(CodingKeys.topLevel) } internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.topLevel) } fileprivate func unqualifiedBaz(_ key: CodingKeys) { print(CodingKeys.topLevel) } private func unqualifiedQux(_ key: CodingKeys) { print(CodingKeys.topLevel) } @@ -209,6 +247,19 @@ struct NonSynthesizedClass : Codable { // expected-note 4 {{'NonSynthesizedClass foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -267,6 +318,7 @@ struct ExplicitClass : Codable { // Qualified type lookup should always be unambiguous. public func qualifiedFoo(_ key: ExplicitClass.CodingKeys) {} + package func qualifiedPkg(_ key: ExplicitClass.CodingKeys) {} internal func qualifiedBar(_ key: ExplicitClass.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExplicitClass.CodingKeys) {} private func qualifiedQux(_ key: ExplicitClass.CodingKeys) {} @@ -277,6 +329,10 @@ struct ExplicitClass : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -302,7 +358,18 @@ struct ExplicitClass : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + pkg(CodingKeys.nested) + } internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -346,6 +413,7 @@ struct ExplicitClass : Codable { struct Nested { // Qualified lookup should remain as-is. public func qualifiedFoo(_ key: ExplicitClass.CodingKeys) {} + package func qualifiedPkg(_ key: ExplicitClass.CodingKeys) {} internal func qualifiedBar(_ key: ExplicitClass.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExplicitClass.CodingKeys) {} private func qualifiedQux(_ key: ExplicitClass.CodingKeys) {} @@ -356,6 +424,10 @@ struct ExplicitClass : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -381,7 +453,18 @@ struct ExplicitClass : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + pkg(CodingKeys.nested) + } internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -436,6 +519,7 @@ struct ExtendedClass : Codable { // Qualified type lookup should always be unambiguous. public func qualifiedFoo(_ key: ExtendedClass.CodingKeys) {} + package func qualifiedPkg(_ key: ExtendedClass.CodingKeys) {} internal func qualifiedBar(_ key: ExtendedClass.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExtendedClass.CodingKeys) {} private func qualifiedQux(_ key: ExtendedClass.CodingKeys) {} @@ -446,6 +530,10 @@ struct ExtendedClass : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -471,7 +559,18 @@ struct ExtendedClass : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + pkg(CodingKeys.nested) + } internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -515,6 +614,7 @@ struct ExtendedClass : Codable { struct Nested { // Qualified lookup should remain as-is. public func qualifiedFoo(_ key: ExtendedClass.CodingKeys) {} + package func qualifiedPkg(_ key: ExtendedClass.CodingKeys) {} internal func qualifiedBar(_ key: ExtendedClass.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExtendedClass.CodingKeys) {} private func qualifiedQux(_ key: ExtendedClass.CodingKeys) {} @@ -525,6 +625,10 @@ struct ExtendedClass : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -550,7 +654,18 @@ struct ExtendedClass : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested diff --git a/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift b/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift index 778e1e8dcce8d..e55e9747c1376 100644 --- a/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift +++ b/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -verify-ignore-unknown +// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -package-name myPkg // A top-level CodingKeys type to fall back to in lookups below. public enum CodingKeys : String, CodingKey { @@ -17,6 +17,7 @@ struct SynthesizedStruct : Codable { // Qualified type lookup should always be unambiguous. public func qualifiedFoo(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared public because its parameter uses a private type}} + package func qualifiedPkg(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared package because its parameter uses a private type}} internal func qualifiedBar(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared internal because its parameter uses a private type}} fileprivate func qualifiedBaz(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared fileprivate because its parameter uses a private type}} private func qualifiedQux(_ key: SynthesizedStruct.CodingKeys) {} @@ -27,6 +28,10 @@ struct SynthesizedStruct : Codable { print(CodingKeys.value) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + print(CodingKeys.value) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} print(CodingKeys.value) // Not found on top-level. } @@ -53,6 +58,19 @@ struct SynthesizedStruct : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} enum CodingKeys : String, CodingKey { case nested @@ -96,6 +114,7 @@ struct SynthesizedStruct : Codable { struct Nested { // Qualified lookup should remain as-is. public func qualifiedFoo(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared public because its parameter uses a private type}} + package func qualifiedPkg(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared package because its parameter uses a private type}} internal func qualifiedBar(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared internal because its parameter uses a private type}} fileprivate func qualifiedBaz(_ key: SynthesizedStruct.CodingKeys) {} // expected-error {{method cannot be declared fileprivate because its parameter uses a private type}} private func qualifiedQux(_ key: SynthesizedStruct.CodingKeys) {} @@ -106,6 +125,10 @@ struct SynthesizedStruct : Codable { print(CodingKeys.value) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + print(CodingKeys.value) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} print(CodingKeys.value) // Not found on top-level. } @@ -132,6 +155,19 @@ struct SynthesizedStruct : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { // expected-error {{method cannot be declared package because its parameter uses a private type}} + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { // expected-error {{method cannot be declared internal because its parameter uses a private type}} enum CodingKeys : String, CodingKey { case nested @@ -177,7 +213,7 @@ struct SynthesizedStruct : Codable { // Structs which don't get synthesized Codable implementations should expose the // appropriate CodingKeys type. -struct NonSynthesizedStruct : Codable { // expected-note 4 {{'NonSynthesizedStruct' declared here}} +struct NonSynthesizedStruct : Codable { // expected-note * {{'NonSynthesizedStruct' declared here}} // No synthesized type since we implemented both methods. init(from decoder: Decoder) throws {} func encode(to encoder: Encoder) throws {} @@ -185,12 +221,14 @@ struct NonSynthesizedStruct : Codable { // expected-note 4 {{'NonSynthesizedStru // Qualified type lookup should clearly fail -- we shouldn't get a synthesized // type here. public func qualifiedFoo(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}} + package func qualifiedPkg(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}} internal func qualifiedBar(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}} fileprivate func qualifiedBaz(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}} private func qualifiedQux(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}} // Unqualified lookups should find the public top-level CodingKeys type. public func unqualifiedFoo(_ key: CodingKeys) { print(CodingKeys.topLevel) } + package func unqualifiedPkg(_ key: CodingKeys) { print(CodingKeys.topLevel) } internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.topLevel) } fileprivate func unqualifiedBaz(_ key: CodingKeys) { print(CodingKeys.topLevel) } private func unqualifiedQux(_ key: CodingKeys) { print(CodingKeys.topLevel) } @@ -209,6 +247,19 @@ struct NonSynthesizedStruct : Codable { // expected-note 4 {{'NonSynthesizedStru foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -267,6 +318,7 @@ struct ExplicitStruct : Codable { // Qualified type lookup should always be unambiguous. public func qualifiedFoo(_ key: ExplicitStruct.CodingKeys) {} + package func qualifiedPkg(_ key: ExplicitStruct.CodingKeys) {} internal func qualifiedBar(_ key: ExplicitStruct.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExplicitStruct.CodingKeys) {} private func qualifiedQux(_ key: ExplicitStruct.CodingKeys) {} @@ -277,6 +329,10 @@ struct ExplicitStruct : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -303,6 +359,19 @@ struct ExplicitStruct : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -346,6 +415,7 @@ struct ExplicitStruct : Codable { struct Nested { // Qualified lookup should remain as-is. public func qualifiedFoo(_ key: ExplicitStruct.CodingKeys) {} + package func qualifiedPkg(_ key: ExplicitStruct.CodingKeys) {} internal func qualifiedBar(_ key: ExplicitStruct.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExplicitStruct.CodingKeys) {} private func qualifiedQux(_ key: ExplicitStruct.CodingKeys) {} @@ -356,6 +426,10 @@ struct ExplicitStruct : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -382,6 +456,19 @@ struct ExplicitStruct : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -436,6 +523,7 @@ struct ExtendedStruct : Codable { // Qualified type lookup should always be unambiguous. public func qualifiedFoo(_ key: ExtendedStruct.CodingKeys) {} + package func qualifiedPkg(_ key: ExplicitStruct.CodingKeys) {} internal func qualifiedBar(_ key: ExtendedStruct.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExtendedStruct.CodingKeys) {} private func qualifiedQux(_ key: ExtendedStruct.CodingKeys) {} @@ -446,6 +534,10 @@ struct ExtendedStruct : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -472,6 +564,19 @@ struct ExtendedStruct : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested @@ -515,6 +620,7 @@ struct ExtendedStruct : Codable { struct Nested { // Qualified lookup should remain as-is. public func qualifiedFoo(_ key: ExtendedStruct.CodingKeys) {} + package func qualifiedPkg(_ key: ExplicitStruct.CodingKeys) {} internal func qualifiedBar(_ key: ExtendedStruct.CodingKeys) {} fileprivate func qualifiedBaz(_ key: ExtendedStruct.CodingKeys) {} private func qualifiedQux(_ key: ExtendedStruct.CodingKeys) {} @@ -525,6 +631,10 @@ struct ExtendedStruct : Codable { print(CodingKeys.a) // Not found on top-level. } + package func unqualifiedPkg(_ key: CodingKeys) { + print(CodingKeys.a) // Not found on top-level. + } + internal func unqualifiedBar(_ key: CodingKeys) { print(CodingKeys.a) // Not found on top-level. } @@ -551,6 +661,19 @@ struct ExtendedStruct : Codable { foo(CodingKeys.nested) } + package func nestedUnqualifiedPkg(_ key: CodingKeys) { + enum CodingKeys : String, CodingKey { + case nested + } + + // CodingKeys should refer to the local unqualified enum. + func pkg(_ key: CodingKeys) { + print(CodingKeys.nested) // Not found on synthesized type or top-level type. + } + + pkg(CodingKeys.nested) + } + internal func nestedUnqualifiedBar(_ key: CodingKeys) { enum CodingKeys : String, CodingKey { case nested diff --git a/test/decl/var/property_wrappers.swift b/test/decl/var/property_wrappers.swift index 2472e6a2eaea6..fa33d07393543 100644 --- a/test/decl/var/property_wrappers.swift +++ b/test/decl/var/property_wrappers.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -swift-version 5 +// RUN: %target-typecheck-verify-swift -swift-version 5 -package-name myPkg // --------------------------------------------------------------------------- // Property wrapper type definitions @@ -620,6 +620,21 @@ public struct HasUsableFromInlineWrapper { // expected-error@-1{{property wrapper type referenced from a '@usableFromInline' property must be '@usableFromInline' or public}} } +public struct HasUsableFromInlinePackageWrapper { + @propertyWrapper + package struct PackageWrapper { // expected-note{{type declared here}} + package var wrappedValue: U + package init(wrappedValue initialValue: U) { + self.wrappedValue = initialValue + } + } + + @PackageWrapper + @usableFromInline + package var y: [T] = [] + // expected-error@-1{{property wrapper type referenced from a '@usableFromInline' property must be '@usableFromInline' or public}} +} + @propertyWrapper class Box { private(set) var wrappedValue: Value