From 2151d6115672e5451aecb43ca04df4e6a6ec89a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 6 Nov 2025 11:48:14 -0800 Subject: [PATCH 1/2] Sema: Support @_implementationOnly protocols --- include/swift/AST/DeclAttr.def | 2 +- lib/Sema/TypeCheckAccess.cpp | 14 +-- test/Sema/hidden-memory-layout.swift | 175 +++++++++++++++++++++++++-- 3 files changed, 171 insertions(+), 20 deletions(-) diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index 5d7ec7df6eab8..cfff48354d0b4 100644 --- a/include/swift/AST/DeclAttr.def +++ b/include/swift/AST/DeclAttr.def @@ -474,7 +474,7 @@ SIMPLE_DECL_ATTR(_alwaysEmitIntoClient, AlwaysEmitIntoClient, 83) SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly, - OnImport | OnFunc | OnConstructor | OnVar | OnSubscript | OnStruct | OnClass | OnEnum, + OnImport | OnFunc | OnConstructor | OnVar | OnSubscript | OnNominalType, UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | UnreachableInABIAttr, 84) diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index 2250437ae0221..0d49728effb24 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -2163,13 +2163,13 @@ swift::getDisallowedOriginKind(const Decl *decl, Feature::AssumeResilientCxxTypes)) return DisallowedOriginKind::FragileCxxAPI; - if (isa(decl) || isa(decl)) { - if (decl->getASTContext().LangOpts.hasFeature( - Feature::CheckImplementationOnly) && - decl->getAttrs().hasAttribute()) { - return DisallowedOriginKind::ImplementationOnlyMemoryLayout; - } - } + // Implementation-only memory layouts for non-library-evolution mode. + // Should we allow references to classes and protocols in non-embedded mode? + if (isa(decl) && + decl->getASTContext().LangOpts.hasFeature( + Feature::CheckImplementationOnly) && + decl->getAttrs().hasAttribute()) + return DisallowedOriginKind::ImplementationOnlyMemoryLayout; // Report non-public import last as it can be ignored by the caller. // See \c diagnoseValueDeclRefExportability. diff --git a/test/Sema/hidden-memory-layout.swift b/test/Sema/hidden-memory-layout.swift index 1e6e53b2c5b1c..dea7536a9e91f 100644 --- a/test/Sema/hidden-memory-layout.swift +++ b/test/Sema/hidden-memory-layout.swift @@ -118,6 +118,33 @@ private enum HiddenEnum { } #endif +public protocol ExposedProtocolPublic { +} + +internal protocol ExposedProtocolInternal { +// expected-note @-1 {{protocol 'ExposedProtocolInternal' is not '@usableFromInline' or public}} +// expected-note @-2 {{type declared here}} +} + +private protocol ExposedProtocolPrivate { +// expected-note @-1 {{protocol 'ExposedProtocolPrivate' is not '@usableFromInline' or public}} +// expected-note @-2 2 {{type declared here}} +} + +#if UseImplementationOnly +@_implementationOnly +private protocol HiddenProtocol { +// expected-opt-in-note @-1 {{protocol 'HiddenProtocol' is not '@usableFromInline' or public}} +// expected-opt-in-note @-2 9 {{protocol declared here}} +// expected-opt-in-note @-3 2 {{type declared here}} +} +#else +private protocol HiddenProtocol { +// expected-not-opt-in-note @-1 1 {{protocol 'HiddenProtocol' is not '@usableFromInline' or public}} +// expected-not-opt-in-note @-2 2 {{type declared here}} +} +#endif + /// Function use sites @inlinable @@ -138,6 +165,14 @@ public func explicitlyInlinable() { let _: HiddenEnum = HiddenEnum.A // expected-error @-1 2 {{enum 'HiddenEnum' is private and cannot be referenced from an '@inlinable' function}} // expected-error @-2 {{enum case 'A' is private and cannot be referenced from an '@inlinable' function}} + + let _: ExposedProtocolPublic + let _: ExposedProtocolInternal + // expected-error @-1 {{protocol 'ExposedProtocolInternal' is internal and cannot be referenced from an '@inlinable' function}} + let _: ExposedProtocolPrivate + // expected-error @-1 {{protocol 'ExposedProtocolPrivate' is private and cannot be referenced from an '@inlinable' function}} + let _: HiddenProtocol + // expected-error @-1 {{protocol 'HiddenProtocol' is private and cannot be referenced from an '@inlinable' function}} } public func implicitlyInlinablePublic() { @@ -150,6 +185,12 @@ public func implicitlyInlinablePublic() { let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A // expected-embedded-opt-in-error @-1 2 {{enum 'HiddenEnum' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenEnum' is marked '@_implementationOnly'}} + + let _: ExposedProtocolPublic + let _: ExposedProtocolInternal + let _: ExposedProtocolPrivate + let _: HiddenProtocol + // expected-embedded-opt-in-error @-1 {{protocol 'HiddenProtocol' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenProtocol' is marked '@_implementationOnly'}} } private func implicitlyInlinablePrivate() { @@ -162,6 +203,12 @@ private func implicitlyInlinablePrivate() { let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A // expected-embedded-opt-in-error @-1 2 {{enum 'HiddenEnum' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenEnum' is marked '@_implementationOnly'}} + + let _: ExposedProtocolPublic + let _: ExposedProtocolInternal + let _: ExposedProtocolPrivate + let _: HiddenProtocol + // expected-embedded-opt-in-error @-1 {{protocol 'HiddenProtocol' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenProtocol' is marked '@_implementationOnly'}} } @_neverEmitIntoClient @@ -172,6 +219,11 @@ public func explicitNonInliable() { let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A + + let _: ExposedProtocolPublic + let _: ExposedProtocolInternal + let _: ExposedProtocolPrivate + let _: HiddenProtocol } @_neverEmitIntoClient @@ -182,6 +234,11 @@ internal func explicitNonInliableInternal() { let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A + + let _: ExposedProtocolPublic + let _: ExposedProtocolInternal + let _: ExposedProtocolPrivate + let _: HiddenProtocol } /// Struct use sites @@ -198,7 +255,6 @@ public struct ExposedLayoutPublicUser: ProtocolFromDirect { private var a: ExposedLayoutPublic private var aa: ExposedLayoutInternal private var b: ExposedLayoutPrivate - private var c: HiddenLayout // expected-opt-in-error @-1 {{cannot use struct 'HiddenLayout' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenLayout' is marked '@_implementationOnly'}} @@ -207,6 +263,15 @@ public struct ExposedLayoutPublicUser: ProtocolFromDirect { private var f: HiddenEnum // expected-opt-in-error @-1 {{cannot use enum 'HiddenEnum' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenEnum' is marked '@_implementationOnly'}} + private var pp: ProtocolFromDirect + // expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} + + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol + // expected-opt-in-error @-1 {{cannot use protocol 'HiddenProtocol' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenProtocol' is marked '@_implementationOnly'}} + private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } @@ -228,6 +293,12 @@ internal struct ExposedLayoutInternalUser: ProtocolFromDirect { private var f: HiddenEnum // expected-opt-in-error @-1 {{cannot use enum 'HiddenEnum' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenEnum' is marked '@_implementationOnly'}} + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol + // expected-opt-in-error @-1 {{cannot use protocol 'HiddenProtocol' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenProtocol' is marked '@_implementationOnly'}} + private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } @@ -249,6 +320,12 @@ private struct ExposedLayoutPrivateUser: ProtocolFromDirect { private var f: HiddenEnum // expected-opt-in-error @-1 {{cannot use enum 'HiddenEnum' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenEnum' is marked '@_implementationOnly'}} + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol + // expected-opt-in-error @-1 {{cannot use protocol 'HiddenProtocol' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenProtocol' is marked '@_implementationOnly'}} + private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } @@ -261,11 +338,17 @@ private struct HiddenLayoutUser { private var a: ExposedLayoutPublic private var aa: ExposedLayoutInternal private var b: ExposedLayoutPrivate + private var c: HiddenLayout private var d: ExposedEnumPublic private var e: ExposedEnumPrivate private var f: HiddenEnum + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol + @_neverEmitIntoClient private func privateFunc(h: HiddenLayout) {} } @@ -273,7 +356,6 @@ private struct HiddenLayoutUser { @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} public struct PublicHiddenStruct {} - #endif /// Enums use sites @@ -281,30 +363,50 @@ public struct PublicHiddenStruct {} public enum PublicEnumUser: ProtocolFromDirect { // expected-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} case a(StructFromDirect) // expected-error {{cannot use struct 'StructFromDirect' here; 'directs' has been imported as implementation-only}} - case b(HiddenLayout) // expected-error {{enum case in a public enum uses a private type}} - // expected-opt-in-error @-1 {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} + + case e(ExposedLayoutPublic) case c(ExposedLayoutInternal) // expected-error {{enum case in a public enum uses an internal type}} case d(ExposedLayoutPrivate) // expected-error {{enum case in a public enum uses a private type}} - case e(ExposedLayoutPublic) + case b(HiddenLayout) // expected-error {{enum case in a public enum uses a private type}} + // expected-opt-in-error @-1 {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} + + case f(ExposedProtocolPublic) + case g(ExposedProtocolInternal) // expected-error {{enum case in a public enum uses an internal type}} + case h(ExposedProtocolPrivate) // expected-error {{enum case in a public enum uses a private type}} + case i(HiddenProtocol) // expected-opt-in-error {{cannot use protocol 'HiddenProtocol' here; 'HiddenProtocol' is marked '@_implementationOnly'}} + // expected-error @-1 {{enum case in a public enum uses a private type}} } internal enum InternalEnumUser: ProtocolFromDirect { // expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} case a(StructFromDirect) // expected-opt-in-error {{cannot use struct 'StructFromDirect' here; 'directs' has been imported as implementation-only}} - case b(HiddenLayout) // expected-opt-in-error {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} - // expected-error @-1 {{enum case in an internal enum uses a private type}} + + case e(ExposedLayoutPublic) case c(ExposedLayoutInternal) case d(ExposedLayoutPrivate) // expected-error {{enum case in an internal enum uses a private type}} - case e(ExposedLayoutPublic) + case b(HiddenLayout) // expected-opt-in-error {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} + // expected-error @-1 {{enum case in an internal enum uses a private type}} + + case f(ExposedProtocolPublic) + case g(ExposedProtocolInternal) + case h(ExposedProtocolPrivate) // expected-error {{enum case in an internal enum uses a private type}} + case i(HiddenProtocol) // expected-opt-in-error {{cannot use protocol 'HiddenProtocol' here; 'HiddenProtocol' is marked '@_implementationOnly'}} + // expected-error @-1 {{enum case in an internal enum uses a private type}} } private enum PrivateEnumUser: ProtocolFromDirect { // expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} case a(StructFromDirect) // expected-opt-in-error {{cannot use struct 'StructFromDirect' here; 'directs' has been imported as implementation-only}} - case b(HiddenLayout) // expected-opt-in-error {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} + + case e(ExposedLayoutPublic) case c(ExposedLayoutInternal) case d(ExposedLayoutPrivate) - case e(ExposedLayoutPublic) + case b(HiddenLayout) // expected-opt-in-error {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} + + case f(ExposedProtocolPublic) + case g(ExposedProtocolInternal) + case h(ExposedProtocolPrivate) + case i(HiddenProtocol) // expected-opt-in-error {{cannot use protocol 'HiddenProtocol' here; 'HiddenProtocol' is marked '@_implementationOnly'}} } internal enum InternalEnumWithRawType : RawTypeFromDirect { // expected-opt-in-error {{cannot use struct 'RawTypeFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} @@ -316,10 +418,16 @@ internal enum InternalEnumWithRawType : RawTypeFromDirect { // expected-opt-in-e @_implementationOnly private enum PrivateHiddenEnumUser: ProtocolFromDirect { case a(StructFromDirect) - case b(HiddenLayout) + + case e(ExposedLayoutPublic) case c(ExposedLayoutInternal) case d(ExposedLayoutPrivate) - case e(ExposedLayoutPublic) + case b(HiddenLayout) + + case f(ExposedProtocolPublic) + case g(ExposedProtocolInternal) + case h(ExposedProtocolPrivate) + case i(HiddenProtocol) } @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} @@ -356,6 +464,12 @@ public class PublicClass: ProtocolFromDirect { private var f: HiddenEnum // expected-opt-in-error @-1 {{cannot use enum 'HiddenEnum' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenEnum' is marked '@_implementationOnly'}} + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol + // expected-opt-in-error @-1 {{cannot use protocol 'HiddenProtocol' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenProtocol' is marked '@_implementationOnly'}} + @_neverEmitIntoClient private func privateFunc(h: HiddenLayout) {} } @@ -381,6 +495,12 @@ internal class InternalClass: ProtocolFromDirect { private var f: HiddenEnum // expected-opt-in-error @-1 {{cannot use enum 'HiddenEnum' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenEnum' is marked '@_implementationOnly'}} + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol + // expected-opt-in-error @-1 {{cannot use protocol 'HiddenProtocol' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenProtocol' is marked '@_implementationOnly'}} + private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } @@ -405,6 +525,12 @@ private class PrivateClass: ProtocolFromDirect { private var f: HiddenEnum // expected-opt-in-error @-1 {{cannot use enum 'HiddenEnum' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenEnum' is marked '@_implementationOnly'}} + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol + // expected-opt-in-error @-1 {{cannot use protocol 'HiddenProtocol' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenProtocol' is marked '@_implementationOnly'}} + private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } @@ -424,8 +550,33 @@ internal class HiddenClass: ProtocolFromDirect { private var d: ExposedEnumPublic private var e: ExposedEnumPrivate private var f: HiddenEnum + + private var g: ExposedProtocolPublic + private var h: ExposedProtocolInternal + private var i: ExposedProtocolPrivate + private var j: HiddenProtocol } @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} public enum PublicHiddenClass {} #endif + +/// Protocol use sites + +public protocol PublicProtocol : ProtocolFromDirect { +// expected-error @-1 {{cannot use protocol 'ProtocolFromDirect' here; 'directs' has been imported as implementation-only}} +} + +internal protocol InternalProtocol : ProtocolFromDirect { +// expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' here; 'directs' has been imported as implementation-only}} +} + +private protocol PrivateProtocol : ProtocolFromDirect { +// expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' here; 'directs' has been imported as implementation-only}} +} + +#if UseImplementationOnly +@_implementationOnly +internal protocol PrivateProtocolHidden : ProtocolFromDirect { +} +#endif From bf5e5b6f1dd97b9a9e1b786c0853f9f5f25779fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Fri, 7 Nov 2025 11:13:07 -0800 Subject: [PATCH 2/2] Sema: Add more tests for class exportability checking in NLE --- test/Sema/hidden-memory-layout.swift | 126 ++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/test/Sema/hidden-memory-layout.swift b/test/Sema/hidden-memory-layout.swift index dea7536a9e91f..195491aa5fe16 100644 --- a/test/Sema/hidden-memory-layout.swift +++ b/test/Sema/hidden-memory-layout.swift @@ -72,6 +72,36 @@ private struct ExposedLayoutPrivate { init() { fatalError() } // expected-note {{initializer 'init()' is not '@usableFromInline' or public}} } +public class ExposedClassPublic { + public init() { fatalError() } +} + +internal class ExposedClassInternal { +// expected-note @-1 {{type declared here}} +} + +private class ExposedClassPrivate { +// expected-note @-1 2 {{class 'ExposedClassPrivate' is not '@usableFromInline' or public}} +// expected-note @-2 2 {{type declared here}} + init() { fatalError() } // expected-note {{initializer 'init()' is not '@usableFromInline' or public}} +} + +#if UseImplementationOnly +@_implementationOnly +private class HiddenClass { +// expected-opt-in-note @-1 2 {{class 'HiddenClass' is not '@usableFromInline' or public}} +// expected-opt-in-note @-2 1 {{initializer 'init()' is not '@usableFromInline' or public}} +// expected-opt-in-note @-3 6 {{class declared here}} +// expected-opt-in-note @-4 2 {{type declared here}} +} +#else +private class HiddenClass { +// expected-not-opt-in-note @-1 2 {{class 'HiddenClass' is not '@usableFromInline' or public}} +// expected-not-opt-in-note @-2 1 {{initializer 'init()' is not '@usableFromInline' or public}} +// expected-not-opt-in-note @-3 2 {{type declared here}} +} +#endif + #if UseImplementationOnly @_implementationOnly private struct HiddenLayout { @@ -158,6 +188,15 @@ public func explicitlyInlinable() { // expected-error @-1 2 {{struct 'HiddenLayout' is private and cannot be referenced from an '@inlinable' function}} // expected-error @-2 {{initializer 'init()' is private and cannot be referenced from an '@inlinable' function}} + let _: ExposedClassPublic = ExposedClassPublic() + let _: ExposedClassPrivate = ExposedClassPrivate() + // expected-error @-1 2 {{class 'ExposedClassPrivate' is private and cannot be referenced from an '@inlinable' function}} + // expected-error @-2 {{initializer 'init()' is private and cannot be referenced from an '@inlinable' function}} + + let _: HiddenClass = HiddenClass() + // expected-error @-1 2 {{class 'HiddenClass' is private and cannot be referenced from an '@inlinable' function}} + // expected-error @-2 {{initializer 'init()' is private and cannot be referenced from an '@inlinable' function}} + let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A // expected-error @-1 2 {{enum 'ExposedEnumPrivate' is private and cannot be referenced from an '@inlinable' function}} @@ -181,6 +220,11 @@ public func implicitlyInlinablePublic() { let _: HiddenLayout = HiddenLayout() // expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} + let _: ExposedClassPublic = ExposedClassPublic() + let _: ExposedClassPrivate = ExposedClassPrivate() + let _: HiddenClass = HiddenClass() + // expected-embedded-opt-in-error @-1 2 {{class 'HiddenClass' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenClass' is marked '@_implementationOnly'}} + let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A @@ -199,6 +243,11 @@ private func implicitlyInlinablePrivate() { let _: HiddenLayout = HiddenLayout() // expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} + let _: ExposedClassPublic = ExposedClassPublic() + let _: ExposedClassPrivate = ExposedClassPrivate() + let _: HiddenClass = HiddenClass() + // expected-embedded-opt-in-error @-1 2 {{class 'HiddenClass' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenClass' is marked '@_implementationOnly'}} + let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A @@ -216,6 +265,11 @@ public func explicitNonInliable() { let _: ExposedLayoutPublic = ExposedLayoutPublic() let _: ExposedLayoutPrivate = ExposedLayoutPrivate() let _: HiddenLayout = HiddenLayout() + + let _: ExposedClassPublic = ExposedClassPublic() + let _: ExposedClassPrivate = ExposedClassPrivate() + let _: HiddenClass = HiddenClass() + let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A @@ -231,6 +285,11 @@ internal func explicitNonInliableInternal() { let _: ExposedLayoutPublic = ExposedLayoutPublic() let _: ExposedLayoutPrivate = ExposedLayoutPrivate() let _: HiddenLayout = HiddenLayout() + + let _: ExposedClassPublic = ExposedClassPublic() + let _: ExposedClassPrivate = ExposedClassPrivate() + let _: HiddenClass = HiddenClass() + let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: HiddenEnum = HiddenEnum.A @@ -258,6 +317,12 @@ public struct ExposedLayoutPublicUser: ProtocolFromDirect { private var c: HiddenLayout // expected-opt-in-error @-1 {{cannot use struct 'HiddenLayout' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenLayout' is marked '@_implementationOnly'}} + private var ca: ExposedClassPublic + private var cb: ExposedClassInternal + private var cc: ExposedClassPrivate + private var cd: HiddenClass + // expected-opt-in-error @-1 {{cannot use class 'HiddenClass' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenClass' is marked '@_implementationOnly'}} + private var d: ExposedEnumPublic private var e: ExposedEnumPrivate private var f: HiddenEnum @@ -274,6 +339,8 @@ public struct ExposedLayoutPublicUser: ProtocolFromDirect { private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} + private func privateFuncClass(h: HiddenClass) {} + // expected-embedded-opt-in-error @-1 {{class 'HiddenClass' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenClass' is marked '@_implementationOnly'}} } internal struct ExposedLayoutInternalUser: ProtocolFromDirect { @@ -288,6 +355,12 @@ internal struct ExposedLayoutInternalUser: ProtocolFromDirect { private var c: HiddenLayout // expected-opt-in-error @-1 {{cannot use struct 'HiddenLayout' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenLayout' is marked '@_implementationOnly'}} + private var ca: ExposedClassPublic + private var cb: ExposedClassInternal + private var cc: ExposedClassPrivate + private var cd: HiddenClass + // expected-opt-in-error @-1 {{cannot use class 'HiddenClass' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenClass' is marked '@_implementationOnly'}} + private var d: ExposedEnumPublic private var e: ExposedEnumPrivate private var f: HiddenEnum @@ -301,6 +374,8 @@ internal struct ExposedLayoutInternalUser: ProtocolFromDirect { private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} + private func privateFuncClass(h: HiddenClass) {} + // expected-embedded-opt-in-error @-1 {{class 'HiddenClass' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenClass' is marked '@_implementationOnly'}} } private struct ExposedLayoutPrivateUser: ProtocolFromDirect { @@ -315,6 +390,12 @@ private struct ExposedLayoutPrivateUser: ProtocolFromDirect { private var c: HiddenLayout // expected-opt-in-error @-1 {{cannot use struct 'HiddenLayout' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenLayout' is marked '@_implementationOnly'}} + private var ca: ExposedClassPublic + private var cb: ExposedClassInternal + private var cc: ExposedClassPrivate + private var cd: HiddenClass + // expected-opt-in-error @-1 {{cannot use class 'HiddenClass' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'HiddenClass' is marked '@_implementationOnly'}} + private var d: ExposedEnumPublic private var e: ExposedEnumPrivate private var f: HiddenEnum @@ -328,6 +409,8 @@ private struct ExposedLayoutPrivateUser: ProtocolFromDirect { private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} + private func privateFuncClass(h: HiddenClass) {} + // expected-embedded-opt-in-error @-1 {{class 'HiddenClass' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenClass' is marked '@_implementationOnly'}} } #if UseImplementationOnly @@ -339,7 +422,13 @@ private struct HiddenLayoutUser { private var aa: ExposedLayoutInternal private var b: ExposedLayoutPrivate + private var ca: ExposedClassPublic + private var cb: ExposedClassInternal + private var cc: ExposedClassPrivate + private var c: HiddenLayout + private var cd: HiddenClass + private var d: ExposedEnumPublic private var e: ExposedEnumPrivate private var f: HiddenEnum @@ -351,6 +440,8 @@ private struct HiddenLayoutUser { @_neverEmitIntoClient private func privateFunc(h: HiddenLayout) {} + @_neverEmitIntoClient + private func privateFuncClass(h: HiddenClass) {} } @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} @@ -370,6 +461,12 @@ public enum PublicEnumUser: ProtocolFromDirect { case b(HiddenLayout) // expected-error {{enum case in a public enum uses a private type}} // expected-opt-in-error @-1 {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} + case ce(ExposedClassPublic) + case cc(ExposedClassInternal) // expected-error {{enum case in a public enum uses an internal type}} + case cd(ExposedClassPrivate) // expected-error {{enum case in a public enum uses a private type}} + case cb(HiddenClass) // expected-error {{enum case in a public enum uses a private type}} + // expected-opt-in-error @-1 {{cannot use class 'HiddenClass' here; 'HiddenClass' is marked '@_implementationOnly'}} + case f(ExposedProtocolPublic) case g(ExposedProtocolInternal) // expected-error {{enum case in a public enum uses an internal type}} case h(ExposedProtocolPrivate) // expected-error {{enum case in a public enum uses a private type}} @@ -387,6 +484,12 @@ internal enum InternalEnumUser: ProtocolFromDirect { case b(HiddenLayout) // expected-opt-in-error {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} // expected-error @-1 {{enum case in an internal enum uses a private type}} + case ce(ExposedClassPublic) + case cc(ExposedClassInternal) + case cd(ExposedClassPrivate) // expected-error {{enum case in an internal enum uses a private type}} + case cb(HiddenClass) // expected-opt-in-error {{cannot use class 'HiddenClass' here; 'HiddenClass' is marked '@_implementationOnly'}} + // expected-error @-1 {{enum case in an internal enum uses a private type}} + case f(ExposedProtocolPublic) case g(ExposedProtocolInternal) case h(ExposedProtocolPrivate) // expected-error {{enum case in an internal enum uses a private type}} @@ -403,6 +506,11 @@ private enum PrivateEnumUser: ProtocolFromDirect { case d(ExposedLayoutPrivate) case b(HiddenLayout) // expected-opt-in-error {{cannot use struct 'HiddenLayout' here; 'HiddenLayout' is marked '@_implementationOnly'}} + case ce(ExposedClassPublic) + case cc(ExposedClassInternal) + case cd(ExposedClassPrivate) + case cb(HiddenClass) // expected-opt-in-error {{cannot use class 'HiddenClass' here; 'HiddenClass' is marked '@_implementationOnly'}} + case f(ExposedProtocolPublic) case g(ExposedProtocolInternal) case h(ExposedProtocolPrivate) @@ -424,6 +532,11 @@ private enum PrivateHiddenEnumUser: ProtocolFromDirect { case d(ExposedLayoutPrivate) case b(HiddenLayout) + case ce(ExposedClassPublic) + case cc(ExposedClassInternal) + case cd(ExposedClassPrivate) + case cb(HiddenClass) + case f(ExposedProtocolPublic) case g(ExposedProtocolInternal) case h(ExposedProtocolPrivate) @@ -443,7 +556,7 @@ internal enum InternalEnumWithRawTypeIO : RawTypeFromDirect { /// Classes use sites -public class PublicClass: ProtocolFromDirect { +public class PublicClassUser: ProtocolFromDirect { // expected-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} public init() { fatalError() } @@ -474,7 +587,7 @@ public class PublicClass: ProtocolFromDirect { private func privateFunc(h: HiddenLayout) {} } -internal class InternalClass: ProtocolFromDirect { +internal class InternalClassUser: ProtocolFromDirect { // expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} public init() { fatalError() } @@ -504,7 +617,7 @@ internal class InternalClass: ProtocolFromDirect { private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } -private class PrivateClass: ProtocolFromDirect { +private class PrivateClassUser: ProtocolFromDirect { // expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} public init() { fatalError() } @@ -536,7 +649,7 @@ private class PrivateClass: ProtocolFromDirect { #if UseImplementationOnly @_implementationOnly -internal class HiddenClass: ProtocolFromDirect { +internal class HiddenClassUser: ProtocolFromDirect { public init() { fatalError() } public var publicField: StructFromDirect @@ -547,6 +660,11 @@ internal class HiddenClass: ProtocolFromDirect { private var b: ExposedLayoutPrivate private var c: HiddenLayout + private var ca: ExposedClassPublic + private var cb: ExposedClassInternal + private var cc: ExposedClassPrivate + private var cd: HiddenClass + private var d: ExposedEnumPublic private var e: ExposedEnumPrivate private var f: HiddenEnum