Merge pull request #85369 from xymus/exportability-nle-classes-and-structs

Sema: Exportability check enums and classes in non-library-evolution mode
This commit is contained in:
Alexis Laferrière
2025-11-07 09:19:25 -08:00
committed by GitHub
7 changed files with 256 additions and 25 deletions

View File

@@ -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)

View File

@@ -3851,7 +3851,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|"
@@ -3870,7 +3870,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|"
@@ -3887,7 +3887,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))
@@ -3952,8 +3952,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,
@@ -7360,7 +7360,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,
@@ -7373,7 +7373,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,

View File

@@ -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<NominalTypeDecl>(VD) &&
VD->getASTContext().LangOpts.hasFeature(
Feature::CheckImplementationOnly) &&
VD->getDeclContext()->getParentModule()->getResilienceStrategy() !=
ResilienceStrategy::Resilient &&
!VD->getAttrs().hasAttribute<ImplementationOnlyAttr>())
return true;
// Case of an enum not marked @_implementationOnly in a non-resilient module?
if (auto *EED = dyn_cast<EnumElementDecl>(VD))
return isExported(EED->getParentEnum());
return false;
}

View File

@@ -5025,12 +5025,12 @@ AttributeChecker::visitImplementationOnlyAttr(ImplementationOnlyAttr *attr) {
return;
}
// @_implementationOnly on structs only applies to non-public types.
auto *VD = cast<ValueDecl>(D);
if (isa<StructDecl>(VD)) {
// @_implementationOnly on types only applies to non-public types.
if (isa<NominalTypeDecl>(D)) {
if (!Ctx.LangOpts.hasFeature(Feature::CheckImplementationOnly)) {
diagnoseAndRemoveAttr(attr,
diag::implementation_only_on_structs_feature);
diagnoseAndRemoveAttr(attr, diag::implementation_only_on_types_feature);
return;
}

View File

@@ -29,3 +29,10 @@ extension StructFromIndirect {
set {}
}
}
public struct RawTypeFromDirect : Equatable, ExpressibleByIntegerLiteral {
public typealias IntegerLiteralType = Int
public init(integerLiteral: Int) {}
}
public protocol ProtocolFromDirect { }

View File

@@ -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

View File

@@ -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'}}