diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index 67eaabe4e88a2..5d7ec7df6eab8 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 ca0028d492e66..55b62b5a2ca8b 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)) @@ -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, @@ -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/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index 2cd0b567ff270..88514a0a0d0ef 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/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 556a95eead8cd..bc4319dd6dede 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/Sema/Inputs/implementation-only-imports/directs.swift b/test/Sema/Inputs/implementation-only-imports/directs.swift index d08c505d508e8..9e0e9d7dc4eb6 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 4d7b7c11c76d7..1e6e53b2c5b1c 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 {{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,26 +135,33 @@ 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() { 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 + 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() { 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 + 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}} @@ -169,13 +200,19 @@ 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 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 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 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}} @@ -184,13 +221,19 @@ private 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 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 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 { +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}} @@ -199,10 +242,15 @@ 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 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 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 @@ -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,4 +272,160 @@ 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: 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 + // 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 + 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: 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 + // 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 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: 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 + // 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 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: ProtocolFromDirect { + 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 + private var f: HiddenEnum +} + +@_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} +public enum PublicHiddenClass {} #endif 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 0000000000000..8383db485cad8 --- /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'}}