Files
swift-mirror/test/Sema/implementation-only-import-embedded.swift
Alexis Laferrière 1b086e1bfc Sema: Embedded functions are fragile unless marked otherwise
Consider functions in embedded mode to be fragile unless marked with
`@_neverEmitIntoClient`. Basically treating them as if they were
`@_alwaysEmitIntoClient` by default. A fragile function cannot reference
restricted imports such as `@_implementationOnly`, `internal import`,
etc.

We consider them as fragile only for type-checking, at the SIL level
they remain treated as normal functions like before. This allows the
later optimization to work as expected. We may want to likely align both
ends of the compiler once this is properly supported in sema.

This is enabled only in embedded. Fragile functions in library-evolution
are marked with attributes and are already checked. We do not need this
is non-embedded non-library-evolution as CMO handles inlining and
already takes into consideration `@_implementationOnly` imports.

Note: We'll need a similar check for memory layouts exposed to clients.
We can still see compiler crashes and miscompiles in this scenario. This
will apply to both embedded and non-library-evolution modes. That will
likely need to extend the `@_neverEmitIntoClient` attribute and may
require a staged deployment.

rdar://161365361
2025-10-14 14:14:54 -07:00

172 lines
8.2 KiB
Swift

/// Test @_implementationOnly import exportability diagnostics in embedded mode.
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -o %t/indirects.swiftmodule \
// RUN: %S/Inputs/implementation-only-imports/indirects.swift \
// RUN: -swift-version 5 -target arm64-apple-macosx15.0 \
// RUN: -enable-experimental-feature Embedded
// RUN: %target-swift-frontend -emit-module -o %t/directs.swiftmodule -I %t\
// RUN: %S/Inputs/implementation-only-imports/directs.swift \
// RUN: -swift-version 5 -target arm64-apple-macosx15.0 \
// RUN: -enable-experimental-feature Embedded
// RUN: %target-swift-frontend -typecheck -verify %s -I %t \
// RUN: -swift-version 5 -target arm64-apple-macosx15.0 \
// RUN: -enable-experimental-feature Embedded
// REQUIRES: swift_feature_Embedded
@_implementationOnly import directs
// expected-warning @-1 {{using '@_implementationOnly' without enabling library evolution for 'main' may lead to instability during execution}}
import indirects
internal func localInternalFunc() {} // expected-note {{global function 'localInternalFunc()' is not '@usableFromInline' or public}}
@inlinable
public func explicitlyInlinable(arg: StructFromDirect = StructFromDirect()) {
// expected-error @-1 {{initializer 'init()' cannot be used in a default argument value because 'directs' was imported implementation-only}}
// expected-error @-2 {{struct 'StructFromDirect' cannot be used in a default argument value because 'directs' was imported implementation-only}}
// expected-error @-3 {{struct 'StructFromDirect' cannot be used in an '@inlinable' function because 'directs' was imported implementation-only}}
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an '@inlinable' function because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an '@inlinable' function because 'directs' was imported implementation-only}}
if (true) {
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an '@inlinable' function because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an '@inlinable' function because 'directs' was imported implementation-only}}
}
func nested() {
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an '@inlinable' function because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an '@inlinable' function because 'directs' was imported implementation-only}}
}
nested()
localInternalFunc() // expected-error {{global function 'localInternalFunc()' is internal and cannot be referenced from an '@inlinable' function}}
explicitlyInlinable()
implicitlyInlinablePublic()
implicitlyInlinablePrivate() // expected-error {{global function 'implicitlyInlinablePrivate(arg:)' is private and cannot be referenced from an '@inlinable' function}}
explicitNonInliable()
}
public func implicitlyInlinablePublic(arg: StructFromDirect = StructFromDirect()) {
// expected-error @-1 {{initializer 'init()' cannot be used in a default argument value because 'directs' was imported implementation-only}}
// expected-error @-2 {{struct 'StructFromDirect' cannot be used in a default argument value because 'directs' was imported implementation-only}}
// expected-error @-3 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
if (true) {
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
}
func nested() {
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
}
nested()
localInternalFunc()
explicitlyInlinable()
implicitlyInlinablePublic()
implicitlyInlinablePrivate()
explicitNonInliable()
}
private func implicitlyInlinablePrivate(arg: StructFromDirect = StructFromDirect()) {
// expected-error @-1 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
// expected-note @-2 {{global function 'implicitlyInlinablePrivate(arg:)' is not '@usableFromInline' or public}}
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
if (true) {
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
}
func nested() {
_ = StructFromDirect() // expected-error {{initializer 'init()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
// expected-error@-1 {{struct 'StructFromDirect' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'directs' was imported implementation-only}}
}
nested()
localInternalFunc()
explicitlyInlinable()
implicitlyInlinablePublic()
implicitlyInlinablePrivate()
explicitNonInliable()
}
@_neverEmitIntoClient
public func explicitNonInliable(arg: StructFromDirect = StructFromDirect()) {
// expected-error @-1 {{initializer 'init()' cannot be used in a default argument value because 'directs' was imported implementation-only}}
// expected-error @-2 {{struct 'StructFromDirect' cannot be used in a default argument value because 'directs' was imported implementation-only}}
// expected-error @-3 {{cannot use struct 'StructFromDirect' here; 'directs' has been imported as implementation-only}}
_ = StructFromDirect()
if (true) {
_ = StructFromDirect()
}
func nested() {
_ = StructFromDirect()
}
nested()
localInternalFunc()
explicitlyInlinable()
implicitlyInlinablePublic()
implicitlyInlinablePrivate()
explicitNonInliable()
}
@_neverEmitIntoClient
internal func explicitNonInliableInternal(arg: StructFromDirect = StructFromDirect()) {
_ = StructFromDirect()
if (true) {
_ = StructFromDirect()
}
func nested() {
_ = StructFromDirect()
}
nested()
localInternalFunc()
explicitlyInlinable()
implicitlyInlinablePublic()
implicitlyInlinablePrivate()
explicitNonInliable()
}
public func legalAccessToIndirect(arg: StructFromIndirect = StructFromIndirect()) {
_ = StructFromIndirect()
if (true) {
_ = StructFromIndirect()
}
func nested() {
_ = StructFromIndirect()
}
nested()
}
public struct ExposedLayoutPublic {
public var publicField: StructFromDirect // expected-error {{cannot use struct 'StructFromDirect' here; 'directs' has been imported as implementation-only}}
private var privateField: StructFromDirect // FIXME should error
}
private struct ExposedLayoutPrivate {
private var privateField: StructFromDirect // FIXME should error
}