Merge pull request #85387 from xymus/exportability-nle-proto

Sema: Exportability check protocols in non-library-evolution mode
This commit is contained in:
Alexis Laferrière
2025-11-12 10:04:04 -08:00
committed by GitHub
3 changed files with 292 additions and 24 deletions

View File

@@ -474,7 +474,7 @@ SIMPLE_DECL_ATTR(_alwaysEmitIntoClient, AlwaysEmitIntoClient,
83) 83)
SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly, 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, UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | UnreachableInABIAttr,
84) 84)

View File

@@ -2163,13 +2163,12 @@ swift::getDisallowedOriginKind(const Decl *decl,
Feature::AssumeResilientCxxTypes)) Feature::AssumeResilientCxxTypes))
return DisallowedOriginKind::FragileCxxAPI; return DisallowedOriginKind::FragileCxxAPI;
if (isa<StructDecl>(decl) || isa<EnumDecl>(decl)) { // Implementation-only memory layouts for non-library-evolution mode.
if (decl->getASTContext().LangOpts.hasFeature( if (isa<NominalTypeDecl>(decl) &&
Feature::CheckImplementationOnly) && decl->getASTContext().LangOpts.hasFeature(
decl->getAttrs().hasAttribute<ImplementationOnlyAttr>()) { Feature::CheckImplementationOnly) &&
return DisallowedOriginKind::ImplementationOnlyMemoryLayout; decl->getAttrs().hasAttribute<ImplementationOnlyAttr>())
} return DisallowedOriginKind::ImplementationOnlyMemoryLayout;
}
// Report non-public import last as it can be ignored by the caller. // Report non-public import last as it can be ignored by the caller.
// See \c diagnoseValueDeclRefExportability. // See \c diagnoseValueDeclRefExportability.

View File

@@ -72,6 +72,36 @@ private struct ExposedLayoutPrivate {
init() { fatalError() } // expected-note {{initializer 'init()' is not '@usableFromInline' or public}} 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 #if UseImplementationOnly
@_implementationOnly @_implementationOnly
private struct HiddenLayout { private struct HiddenLayout {
@@ -118,6 +148,33 @@ private enum HiddenEnum {
} }
#endif #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 /// Function use sites
@inlinable @inlinable
@@ -131,6 +188,15 @@ public func explicitlyInlinable() {
// expected-error @-1 2 {{struct 'HiddenLayout' is private and cannot be referenced from an '@inlinable' function}} // 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}} // 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 _: ExposedEnumPublic = ExposedEnumPublic.A
let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A
// expected-error @-1 2 {{enum 'ExposedEnumPrivate' is private and cannot be referenced from an '@inlinable' function}} // expected-error @-1 2 {{enum 'ExposedEnumPrivate' is private and cannot be referenced from an '@inlinable' function}}
@@ -138,6 +204,14 @@ public func explicitlyInlinable() {
let _: HiddenEnum = HiddenEnum.A let _: HiddenEnum = HiddenEnum.A
// expected-error @-1 2 {{enum 'HiddenEnum' is private and cannot be referenced from an '@inlinable' function}} // 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}} // 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() { public func implicitlyInlinablePublic() {
@@ -146,10 +220,21 @@ public func implicitlyInlinablePublic() {
let _: HiddenLayout = HiddenLayout() let _: HiddenLayout = HiddenLayout()
// expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}} // expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' 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 '@export(interface)' because 'HiddenClass' is marked '@_implementationOnly'}}
let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPublic = ExposedEnumPublic.A
let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A
let _: HiddenEnum = HiddenEnum.A let _: HiddenEnum = HiddenEnum.A
// expected-embedded-opt-in-error @-1 2 {{enum 'HiddenEnum' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenEnum' is marked '@_implementationOnly'}} // expected-embedded-opt-in-error @-1 2 {{enum 'HiddenEnum' cannot be used in an embedded function not marked '@export(interface)' 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 '@export(interface)' because 'HiddenProtocol' is marked '@_implementationOnly'}}
} }
private func implicitlyInlinablePrivate() { private func implicitlyInlinablePrivate() {
@@ -158,10 +243,21 @@ private func implicitlyInlinablePrivate() {
let _: HiddenLayout = HiddenLayout() let _: HiddenLayout = HiddenLayout()
// expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}} // expected-embedded-opt-in-error @-1 2 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' 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 '@export(interface)' because 'HiddenClass' is marked '@_implementationOnly'}}
let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPublic = ExposedEnumPublic.A
let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A
let _: HiddenEnum = HiddenEnum.A let _: HiddenEnum = HiddenEnum.A
// expected-embedded-opt-in-error @-1 2 {{enum 'HiddenEnum' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenEnum' is marked '@_implementationOnly'}} // expected-embedded-opt-in-error @-1 2 {{enum 'HiddenEnum' cannot be used in an embedded function not marked '@export(interface)' 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 '@export(interface)' because 'HiddenProtocol' is marked '@_implementationOnly'}}
} }
@export(interface) @export(interface)
@@ -169,9 +265,19 @@ public func explicitNonInliable() {
let _: ExposedLayoutPublic = ExposedLayoutPublic() let _: ExposedLayoutPublic = ExposedLayoutPublic()
let _: ExposedLayoutPrivate = ExposedLayoutPrivate() let _: ExposedLayoutPrivate = ExposedLayoutPrivate()
let _: HiddenLayout = HiddenLayout() let _: HiddenLayout = HiddenLayout()
let _: ExposedClassPublic = ExposedClassPublic()
let _: ExposedClassPrivate = ExposedClassPrivate()
let _: HiddenClass = HiddenClass()
let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPublic = ExposedEnumPublic.A
let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A
let _: HiddenEnum = HiddenEnum.A let _: HiddenEnum = HiddenEnum.A
let _: ExposedProtocolPublic
let _: ExposedProtocolInternal
let _: ExposedProtocolPrivate
let _: HiddenProtocol
} }
@export(interface) @export(interface)
@@ -179,9 +285,19 @@ internal func explicitNonInliableInternal() {
let _: ExposedLayoutPublic = ExposedLayoutPublic() let _: ExposedLayoutPublic = ExposedLayoutPublic()
let _: ExposedLayoutPrivate = ExposedLayoutPrivate() let _: ExposedLayoutPrivate = ExposedLayoutPrivate()
let _: HiddenLayout = HiddenLayout() let _: HiddenLayout = HiddenLayout()
let _: ExposedClassPublic = ExposedClassPublic()
let _: ExposedClassPrivate = ExposedClassPrivate()
let _: HiddenClass = HiddenClass()
let _: ExposedEnumPublic = ExposedEnumPublic.A let _: ExposedEnumPublic = ExposedEnumPublic.A
let _: ExposedEnumPrivate = ExposedEnumPrivate.A let _: ExposedEnumPrivate = ExposedEnumPrivate.A
let _: HiddenEnum = HiddenEnum.A let _: HiddenEnum = HiddenEnum.A
let _: ExposedProtocolPublic
let _: ExposedProtocolInternal
let _: ExposedProtocolPrivate
let _: HiddenProtocol
} }
/// Struct use sites /// Struct use sites
@@ -198,17 +314,33 @@ public struct ExposedLayoutPublicUser: ProtocolFromDirect {
private var a: ExposedLayoutPublic private var a: ExposedLayoutPublic
private var aa: ExposedLayoutInternal private var aa: ExposedLayoutInternal
private var b: ExposedLayoutPrivate private var b: ExposedLayoutPrivate
private var c: HiddenLayout 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'}} // 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 d: ExposedEnumPublic
private var e: ExposedEnumPrivate private var e: ExposedEnumPrivate
private var f: HiddenEnum 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'}} // 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) {} private func privateFunc(h: HiddenLayout) {}
// expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' 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 '@export(interface)' because 'HiddenClass' is marked '@_implementationOnly'}}
} }
internal struct ExposedLayoutInternalUser: ProtocolFromDirect { internal struct ExposedLayoutInternalUser: ProtocolFromDirect {
@@ -223,13 +355,27 @@ internal struct ExposedLayoutInternalUser: ProtocolFromDirect {
private var c: HiddenLayout 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'}} // 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 d: ExposedEnumPublic
private var e: ExposedEnumPrivate private var e: ExposedEnumPrivate
private var f: HiddenEnum 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'}} // 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) {} private func privateFunc(h: HiddenLayout) {}
// expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' 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 '@export(interface)' because 'HiddenClass' is marked '@_implementationOnly'}}
} }
private struct ExposedLayoutPrivateUser: ProtocolFromDirect { private struct ExposedLayoutPrivateUser: ProtocolFromDirect {
@@ -244,13 +390,27 @@ private struct ExposedLayoutPrivateUser: ProtocolFromDirect {
private var c: HiddenLayout 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'}} // 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 d: ExposedEnumPublic
private var e: ExposedEnumPrivate private var e: ExposedEnumPrivate
private var f: HiddenEnum 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'}} // 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) {} private func privateFunc(h: HiddenLayout) {}
// expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}} // expected-embedded-opt-in-error @-1 {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' 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 '@export(interface)' because 'HiddenClass' is marked '@_implementationOnly'}}
} }
#if UseImplementationOnly #if UseImplementationOnly
@@ -261,19 +421,32 @@ private struct HiddenLayoutUser {
private var a: ExposedLayoutPublic private var a: ExposedLayoutPublic
private var aa: ExposedLayoutInternal private var aa: ExposedLayoutInternal
private var b: ExposedLayoutPrivate private var b: ExposedLayoutPrivate
private var ca: ExposedClassPublic
private var cb: ExposedClassInternal
private var cc: ExposedClassPrivate
private var c: HiddenLayout private var c: HiddenLayout
private var cd: HiddenClass
private var d: ExposedEnumPublic private var d: ExposedEnumPublic
private var e: ExposedEnumPrivate private var e: ExposedEnumPrivate
private var f: HiddenEnum private var f: HiddenEnum
private var g: ExposedProtocolPublic
private var h: ExposedProtocolInternal
private var i: ExposedProtocolPrivate
private var j: HiddenProtocol
@export(interface) @export(interface)
private func privateFunc(h: HiddenLayout) {} private func privateFunc(h: HiddenLayout) {}
@export(interface)
private func privateFuncClass(h: HiddenClass) {}
} }
@_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}} @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}}
public struct PublicHiddenStruct {} public struct PublicHiddenStruct {}
#endif #endif
/// Enums use sites /// Enums use sites
@@ -281,30 +454,67 @@ public struct PublicHiddenStruct {}
public enum PublicEnumUser: ProtocolFromDirect { public enum PublicEnumUser: ProtocolFromDirect {
// expected-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}} // 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 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 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 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 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}}
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 { 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}} // 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 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 c(ExposedLayoutInternal)
case d(ExposedLayoutPrivate) // expected-error {{enum case in an internal enum uses a private type}} 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 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}}
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 { 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}} // 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 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 c(ExposedLayoutInternal)
case d(ExposedLayoutPrivate) case d(ExposedLayoutPrivate)
case e(ExposedLayoutPublic) 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)
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}} 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 +526,21 @@ internal enum InternalEnumWithRawType : RawTypeFromDirect { // expected-opt-in-e
@_implementationOnly @_implementationOnly
private enum PrivateHiddenEnumUser: ProtocolFromDirect { private enum PrivateHiddenEnumUser: ProtocolFromDirect {
case a(StructFromDirect) case a(StructFromDirect)
case b(HiddenLayout)
case e(ExposedLayoutPublic)
case c(ExposedLayoutInternal) case c(ExposedLayoutInternal)
case d(ExposedLayoutPrivate) case d(ExposedLayoutPrivate)
case e(ExposedLayoutPublic) case b(HiddenLayout)
case ce(ExposedClassPublic)
case cc(ExposedClassInternal)
case cd(ExposedClassPrivate)
case cb(HiddenClass)
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}} @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}}
@@ -335,7 +556,7 @@ internal enum InternalEnumWithRawTypeIO : RawTypeFromDirect {
/// Classes use sites /// 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}} // expected-error @-1 {{cannot use protocol 'ProtocolFromDirect' in a public or '@usableFromInline' conformance; 'directs' has been imported as implementation-only}}
public init() { fatalError() } public init() { fatalError() }
@@ -356,11 +577,17 @@ public class PublicClass: ProtocolFromDirect {
private var f: HiddenEnum 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'}} // 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'}}
@export(interface) @export(interface)
private func privateFunc(h: HiddenLayout) {} 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}} // 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 init() { fatalError() }
@@ -381,10 +608,16 @@ internal class InternalClass: ProtocolFromDirect {
private var f: HiddenEnum 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'}} // 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 '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}} private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' 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}} // 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 init() { fatalError() }
@@ -405,12 +638,18 @@ private class PrivateClass: ProtocolFromDirect {
private var f: HiddenEnum 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'}} // 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 '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}} private func privateFunc(h: HiddenLayout) {} // expected-embedded-opt-in-error {{struct 'HiddenLayout' cannot be used in an embedded function not marked '@export(interface)' because 'HiddenLayout' is marked '@_implementationOnly'}}
} }
#if UseImplementationOnly #if UseImplementationOnly
@_implementationOnly @_implementationOnly
internal class HiddenClass: ProtocolFromDirect { internal class HiddenClassUser: ProtocolFromDirect {
public init() { fatalError() } public init() { fatalError() }
public var publicField: StructFromDirect public var publicField: StructFromDirect
@@ -421,11 +660,41 @@ internal class HiddenClass: ProtocolFromDirect {
private var b: ExposedLayoutPrivate private var b: ExposedLayoutPrivate
private var c: HiddenLayout 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 d: ExposedEnumPublic
private var e: ExposedEnumPrivate private var e: ExposedEnumPrivate
private var f: HiddenEnum 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}} @_implementationOnly // expected-opt-in-error {{'@_implementationOnly' may not be used on public declarations}}
public enum PublicHiddenClass {} public enum PublicHiddenClass {}
#endif #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