From dd55d0d827d8bbd6b546ee700825090512685635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 4 Nov 2025 15:13:00 -0800 Subject: [PATCH 1/5] Sema: Fix access-level of ExposedLayoutInternalUser in tests --- test/Sema/hidden-memory-layout.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Sema/hidden-memory-layout.swift b/test/Sema/hidden-memory-layout.swift index 4d7b7c11c76d..92a360999cf0 100644 --- a/test/Sema/hidden-memory-layout.swift +++ b/test/Sema/hidden-memory-layout.swift @@ -175,7 +175,7 @@ public struct ExposedLayoutPublicUser { // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because it is a struct marked '@_implementationOnly'}} } -private struct ExposedLayoutInternalUser { +internal struct ExposedLayoutInternalUser { private var privateField: StructFromDirect // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} From b52781e1e1335962124dc58b3c74d62ccce29cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 4 Nov 2025 14:17:28 -0800 Subject: [PATCH 2/5] Sema: Generalize the diagnostic about types with @_implementationOnly --- include/swift/AST/DiagnosticsSema.def | 10 +++++----- test/Sema/hidden-memory-layout.swift | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index ca0028d492e6..0a3c966ae963 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -3848,7 +3848,7 @@ ERROR(decl_from_hidden_module,none, "C++ types from imported module %2 do not support library evolution|" "it was imported via the internal bridging header|" "%2 was not imported publicly|" - "it is a struct marked '@_implementationOnly'}3", + "%0 is marked '@_implementationOnly'}3", (const Decl *, unsigned, Identifier, unsigned)) ERROR(typealias_desugars_to_type_from_hidden_module,none, "%0 aliases '%1.%2' and cannot be used %select{here|" @@ -3867,7 +3867,7 @@ ERROR(typealias_desugars_to_type_from_hidden_module,none, "C++ types from imported module %4 do not support library evolution|" "it was imported via the internal bridging header|" "%4 was not imported publicly|" - "it is a struct marked '@_implementationOnly'}5", + "%0 is marked '@_implementationOnly'}5", (const TypeAliasDecl *, StringRef, StringRef, unsigned, Identifier, unsigned)) ERROR(conformance_from_implementation_only_module,none, "cannot use conformance of %0 to %1 %select{here|as property wrapper here|" @@ -3884,7 +3884,7 @@ ERROR(conformance_from_implementation_only_module,none, "C++ types from imported module %3 do not support library evolution|" "it was imported via the internal bridging header|" "%3 was not imported publicly|" - "it is a struct marked '@_implementationOnly'}4", + "%0 is marked '@_implementationOnly'}4", (Type, Identifier, unsigned, Identifier, unsigned)) NOTE(assoc_conformance_from_implementation_only_module,none, "in associated type %0 (inferred as %1)", (Type, Type)) @@ -7353,7 +7353,7 @@ ERROR(inlinable_decl_ref_from_hidden_module, "C++ APIs from imported module %2 do not support library evolution|" "it was imported via the internal bridging header|" "%2 was not imported publicly|" - "it is a struct marked '@_implementationOnly'}3", + "%0 is marked '@_implementationOnly'}3", (const ValueDecl *, unsigned, Identifier, unsigned)) ERROR(inlinable_typealias_desugars_to_type_from_hidden_module, @@ -7366,7 +7366,7 @@ ERROR(inlinable_typealias_desugars_to_type_from_hidden_module, "C++ types from imported module %4 do not support library evolution|" "it was imported via the internal bridging header|" "%4 was not imported publicly|" - "it is a struct marked '@_implementationOnly'}5", + "%0 is marked '@_implementationOnly'}5", (const TypeAliasDecl *, StringRef, StringRef, unsigned, Identifier, unsigned)) NOTE(missing_import_inserted, diff --git a/test/Sema/hidden-memory-layout.swift b/test/Sema/hidden-memory-layout.swift index 92a360999cf0..90aca1d5abb5 100644 --- a/test/Sema/hidden-memory-layout.swift +++ b/test/Sema/hidden-memory-layout.swift @@ -120,7 +120,7 @@ public func implicitlyInlinablePublic() { let _: ExposedLayoutPublic = ExposedLayoutPublic() let _: ExposedLayoutPrivate = ExposedLayoutPrivate() let _: HiddenLayout = HiddenLayout() - // expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because it is a struct marked '@_implementationOnly'}} + // 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 _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A @@ -130,7 +130,7 @@ private func implicitlyInlinablePrivate() { let _: ExposedLayoutPublic = ExposedLayoutPublic() let _: ExposedLayoutPrivate = ExposedLayoutPrivate() let _: HiddenLayout = HiddenLayout() - // expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because it is a struct marked '@_implementationOnly'}} + // 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 _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A @@ -169,10 +169,10 @@ public struct ExposedLayoutPublicUser { 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; it is a struct marked '@_implementationOnly'}} + // 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 func privateFunc(h: HiddenLayout) {} - // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because it is a struct marked '@_implementationOnly'}} + // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } internal struct ExposedLayoutInternalUser { @@ -184,10 +184,10 @@ internal struct ExposedLayoutInternalUser { 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; it is a struct marked '@_implementationOnly'}} + // 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 func privateFunc(h: HiddenLayout) {} - // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because it is a struct marked '@_implementationOnly'}} + // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } private struct ExposedLayoutPrivateUser { @@ -199,10 +199,10 @@ private struct ExposedLayoutPrivateUser { 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; it is a struct marked '@_implementationOnly'}} + // 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 func privateFunc(h: HiddenLayout) {} - // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because it is a struct marked '@_implementationOnly'}} + // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'HiddenLayout' is marked '@_implementationOnly'}} } #if UseImplementationOnly From 5bffd70452f26ffcc2a8fe9d1b199e690ce9bf7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 23 Oct 2025 09:53:24 -0700 Subject: [PATCH 3/5] Sema: Accept @_implementationOnly on enums and classes --- include/swift/AST/DeclAttr.def | 2 +- include/swift/AST/DiagnosticsSema.def | 4 ++-- lib/Sema/TypeCheckAttr.cpp | 8 ++++---- ...tr_implementation_only_on_types_feature_required.swift | 4 ++++ 4 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 test/attr/attr_implementation_only_on_types_feature_required.swift diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index 67eaabe4e88a..5d7ec7df6eab 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, + OnImport | OnFunc | OnConstructor | OnVar | OnSubscript | OnStruct | OnClass | OnEnum, UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | UnreachableInABIAttr, 84) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 0a3c966ae963..55b62b5a2ca8 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -3949,8 +3949,8 @@ ERROR(implementation_only_override_import_without_attr,none, "override of %kindonly0 imported as implementation-only must be declared " "'@_implementationOnly'", (const ValueDecl *)) -ERROR(implementation_only_on_structs_feature,none, - "'@_implementationOnly' on structs requires " +ERROR(implementation_only_on_types_feature,none, + "'@_implementationOnly' on a type requires " "'-enable-experimental-feature CheckImplementationOnly'", ()) ERROR(import_attr_conflict,none, diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 556a95eead8c..bc4319dd6ded 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -4995,12 +4995,12 @@ AttributeChecker::visitImplementationOnlyAttr(ImplementationOnlyAttr *attr) { return; } - // @_implementationOnly on structs only applies to non-public types. auto *VD = cast(D); - if (isa(VD)) { + + // @_implementationOnly on types only applies to non-public types. + if (isa(D)) { if (!Ctx.LangOpts.hasFeature(Feature::CheckImplementationOnly)) { - diagnoseAndRemoveAttr(attr, - diag::implementation_only_on_structs_feature); + diagnoseAndRemoveAttr(attr, diag::implementation_only_on_types_feature); return; } diff --git a/test/attr/attr_implementation_only_on_types_feature_required.swift b/test/attr/attr_implementation_only_on_types_feature_required.swift new file mode 100644 index 000000000000..8383db485cad --- /dev/null +++ b/test/attr/attr_implementation_only_on_types_feature_required.swift @@ -0,0 +1,4 @@ +// RUN: %target-typecheck-verify-swift %s + +@_implementationOnly struct MyStruct {} +// expected-error@-1{{'@_implementationOnly' on a type requires '-enable-experimental-feature CheckImplementationOnly'}} From 8567630802c7f850ee6769901765dccfa8ee6552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 4 Nov 2025 14:56:03 -0800 Subject: [PATCH 4/5] Sema: Test @_implementationOnly classes --- test/Sema/hidden-memory-layout.swift | 86 +++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/test/Sema/hidden-memory-layout.swift b/test/Sema/hidden-memory-layout.swift index 90aca1d5abb5..9459f7ec982d 100644 --- a/test/Sema/hidden-memory-layout.swift +++ b/test/Sema/hidden-memory-layout.swift @@ -76,7 +76,7 @@ private struct HiddenLayout { // expected-opt-in-note @-1 2 {{struct 'HiddenLayout' is not '@usableFromInline' or public}} // expected-opt-in-note @-2 1 {{initializer 'init()' is not '@usableFromInline' or public}} // expected-opt-in-note @-3 2 {{struct declared here}} -// expected-opt-in-note @-4 {{struct declared here}} +// expected-opt-in-note @-4 4 {{struct declared here}} } #else private struct HiddenLayout { @@ -222,3 +222,87 @@ private struct HiddenLayoutUser { @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} public struct PublicHiddenStruct {} #endif + +/// Classes use sites + +public class PublicClass { + public init() { fatalError() } + + public var publicField: StructFromDirect + // expected-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} + + private var privateField: StructFromDirect + // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} + 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'}} + + private var d: ExposedEnumPublic + private var e: ExposedEnumPrivate + + @_neverEmitIntoClient + private func privateFunc(h: HiddenLayout) {} +} + +internal class InternalClass { + public init() { fatalError() } + + public var publicField: StructFromDirect + // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} + private var privateField: StructFromDirect + // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} + + 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'}} + + private var d: ExposedEnumPublic + private var e: ExposedEnumPrivate + + 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 { + public init() { fatalError() } + + public var publicField: StructFromDirect + // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} + private var privateField: StructFromDirect + // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} + + 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'}} + + private var d: ExposedEnumPublic + private var e: ExposedEnumPrivate + + 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'}} +} + +#if UseImplementationOnly +@_implementationOnly +internal class HiddenClass { + public init() { fatalError() } + + public var publicField: StructFromDirect + private var privateField: StructFromDirect + + private var a: ExposedLayoutPublic + private var aa: ExposedLayoutInternal + private var b: ExposedLayoutPrivate + private var c: HiddenLayout + + private var d: ExposedEnumPublic + private var e: ExposedEnumPrivate +} + +@_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} +public enum PublicHiddenClass {} +#endif From b107169153de5e28801bddfd986da9a3967ee388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 4 Nov 2025 15:33:41 -0800 Subject: [PATCH 5/5] Sema: Exportability check super types --- lib/AST/Availability.cpp | 13 ++ .../implementation-only-imports/directs.swift | 7 + test/Sema/hidden-memory-layout.swift | 141 ++++++++++++++++-- 3 files changed, 152 insertions(+), 9 deletions(-) diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index 2cd0b567ff27..88514a0a0d0e 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -1009,6 +1009,19 @@ bool swift::isExported(const ValueDecl *VD) { if (property->isLayoutExposedToClients(/*applyImplicit=*/true)) return true; + // Is this a type exposed by default in a non-resilient module? + if (isa(VD) && + VD->getASTContext().LangOpts.hasFeature( + Feature::CheckImplementationOnly) && + VD->getDeclContext()->getParentModule()->getResilienceStrategy() != + ResilienceStrategy::Resilient && + !VD->getAttrs().hasAttribute()) + return true; + + // Case of an enum not marked @_implementationOnly in a non-resilient module? + if (auto *EED = dyn_cast(VD)) + return isExported(EED->getParentEnum()); + return false; } diff --git a/test/Sema/Inputs/implementation-only-imports/directs.swift b/test/Sema/Inputs/implementation-only-imports/directs.swift index d08c505d508e..9e0e9d7dc4eb 100644 --- a/test/Sema/Inputs/implementation-only-imports/directs.swift +++ b/test/Sema/Inputs/implementation-only-imports/directs.swift @@ -29,3 +29,10 @@ extension StructFromIndirect { set {} } } + +public struct RawTypeFromDirect : Equatable, ExpressibleByIntegerLiteral { + public typealias IntegerLiteralType = Int + public init(integerLiteral: Int) {} +} + +public protocol ProtocolFromDirect { } diff --git a/test/Sema/hidden-memory-layout.swift b/test/Sema/hidden-memory-layout.swift index 9459f7ec982d..1e6e53b2c5b1 100644 --- a/test/Sema/hidden-memory-layout.swift +++ b/test/Sema/hidden-memory-layout.swift @@ -63,10 +63,12 @@ public struct ExposedLayoutPublic { } internal struct ExposedLayoutInternal { +// expected-note @-1 {{type declared here}} } private struct ExposedLayoutPrivate { // expected-note @-1 2 {{struct 'ExposedLayoutPrivate' is not '@usableFromInline' or public}} +// expected-note @-2 2 {{type declared here}} init() { fatalError() } // expected-note {{initializer 'init()' is not '@usableFromInline' or public}} } @@ -75,13 +77,14 @@ private struct ExposedLayoutPrivate { private struct HiddenLayout { // expected-opt-in-note @-1 2 {{struct 'HiddenLayout' is not '@usableFromInline' or public}} // expected-opt-in-note @-2 1 {{initializer 'init()' is not '@usableFromInline' or public}} -// expected-opt-in-note @-3 2 {{struct declared here}} -// expected-opt-in-note @-4 4 {{struct declared here}} +// expected-opt-in-note @-3 9 {{struct declared here}} +// expected-opt-in-note @-4 2 {{type declared here}} } #else private struct HiddenLayout { // expected-not-opt-in-note @-1 2 {{struct 'HiddenLayout' 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 @@ -97,6 +100,24 @@ private enum ExposedEnumPrivate { case B } +#if UseImplementationOnly +@_implementationOnly +private enum HiddenEnum { +// expected-opt-in-note @-1 6 {{enum declared here}} +// expected-opt-in-note @-2 2 {{enum 'HiddenEnum' is not '@usableFromInline' or public}} + case A +// expected-opt-in-note @-1 {{enum case 'A' is not '@usableFromInline' or public}} + case B +} +#else +private enum HiddenEnum { +// expected-not-opt-in-note @-1 2 {{enum 'HiddenEnum' is not '@usableFromInline' or public}} + case A +// expected-not-opt-in-note @-1 {{enum case 'A' is not '@usableFromInline' or public}} + case B +} +#endif + /// Function use sites @inlinable @@ -114,6 +135,9 @@ public func explicitlyInlinable() { let _: ExposedEnumPrivate = ExposedEnumPrivate.A // expected-error @-1 2 {{enum 'ExposedEnumPrivate' 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 _: 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}} } public func implicitlyInlinablePublic() { @@ -124,6 +148,8 @@ public func implicitlyInlinablePublic() { let _: ExposedEnumPublic = ExposedEnumPublic.A 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'}} } private func implicitlyInlinablePrivate() { @@ -134,6 +160,8 @@ private func implicitlyInlinablePrivate() { let _: ExposedEnumPublic = ExposedEnumPublic.A 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'}} } @_neverEmitIntoClient @@ -143,6 +171,7 @@ public func explicitNonInliable() { let _: HiddenLayout = HiddenLayout() let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A + let _: HiddenEnum = HiddenEnum.A } @_neverEmitIntoClient @@ -152,11 +181,13 @@ internal func explicitNonInliableInternal() { let _: HiddenLayout = HiddenLayout() let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A + let _: HiddenEnum = HiddenEnum.A } /// Struct use sites -public struct ExposedLayoutPublicUser { +public struct ExposedLayoutPublicUser: ProtocolFromDirect { +// expected-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} public var publicField: StructFromDirect // expected-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} @@ -171,11 +202,17 @@ public struct ExposedLayoutPublicUser { 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 d: ExposedEnumPublic + private var e: ExposedEnumPrivate + 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 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'}} } -internal struct ExposedLayoutInternalUser { +internal struct ExposedLayoutInternalUser: ProtocolFromDirect { +// expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} private var privateField: StructFromDirect // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} @@ -186,11 +223,17 @@ internal struct ExposedLayoutInternalUser { 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 d: ExposedEnumPublic + private var e: ExposedEnumPrivate + 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 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 struct ExposedLayoutPrivateUser { +private struct ExposedLayoutPrivateUser: ProtocolFromDirect { +// expected-opt-in-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} private var privateField: StructFromDirect // expected-opt-in-error @-1 {{cannot use struct 'StructFromDirect' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'directs' has been imported as implementation-only}} @@ -201,6 +244,11 @@ private struct ExposedLayoutPrivateUser { 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 d: ExposedEnumPublic + private var e: ExposedEnumPrivate + 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 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'}} } @@ -214,6 +262,9 @@ private struct HiddenLayoutUser { private var aa: ExposedLayoutInternal private var b: ExposedLayoutPrivate private var c: HiddenLayout + private var d: ExposedEnumPublic + private var e: ExposedEnumPrivate + private var f: HiddenEnum @_neverEmitIntoClient private func privateFunc(h: HiddenLayout) {} @@ -221,11 +272,72 @@ private struct HiddenLayoutUser { @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} public struct PublicHiddenStruct {} + + +#endif + +/// Enums use sites + +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 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) +} + +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 c(ExposedLayoutInternal) + case d(ExposedLayoutPrivate) // expected-error {{enum case in an internal enum uses a private type}} + case e(ExposedLayoutPublic) +} + +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 c(ExposedLayoutInternal) + case d(ExposedLayoutPrivate) + case e(ExposedLayoutPublic) +} + +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}} + typealias RawValue = RawTypeFromDirect + case a +} + +#if UseImplementationOnly +@_implementationOnly +private enum PrivateHiddenEnumUser: ProtocolFromDirect { + case a(StructFromDirect) + case b(HiddenLayout) + case c(ExposedLayoutInternal) + case d(ExposedLayoutPrivate) + case e(ExposedLayoutPublic) +} + +@_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} +public enum PublicHiddenEnum {} + +@_implementationOnly +internal enum InternalEnumWithRawTypeIO : RawTypeFromDirect { + typealias RawValue = RawTypeFromDirect + case a +} + #endif /// Classes use sites -public class PublicClass { +public class PublicClass: ProtocolFromDirect { +// expected-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} + public init() { fatalError() } public var publicField: StructFromDirect @@ -241,12 +353,16 @@ public class PublicClass { private var d: ExposedEnumPublic private var e: ExposedEnumPrivate + 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'}} @_neverEmitIntoClient private func privateFunc(h: HiddenLayout) {} } -internal class InternalClass { +internal class InternalClass: 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() } public var publicField: StructFromDirect @@ -262,11 +378,15 @@ internal class InternalClass { private var d: ExposedEnumPublic private var e: ExposedEnumPrivate + 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 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 { +private class PrivateClass: 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() } public var publicField: StructFromDirect @@ -282,13 +402,15 @@ private class PrivateClass { private var d: ExposedEnumPublic private var e: ExposedEnumPrivate + 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 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'}} } #if UseImplementationOnly @_implementationOnly -internal class HiddenClass { +internal class HiddenClass: ProtocolFromDirect { public init() { fatalError() } public var publicField: StructFromDirect @@ -301,6 +423,7 @@ internal class HiddenClass { private var d: ExposedEnumPublic private var e: ExposedEnumPrivate + private var f: HiddenEnum } @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}}