[SE-0497] Implement @export attribute syntax

Implement the @export(implementation) and @export(interface) attributes
to replace @_alwaysEmitIntoClient and @_neverEmitIntoClient. Provide a
warning + Fix-It to start staging out the very-new
@_neverEmitIntoClient. We'll hold off on pushing folks toward
@_alwaysEmitIntoClient for a little longer.
This commit is contained in:
Doug Gregor
2025-11-07 16:20:43 -08:00
parent ed85a12b59
commit 020b69d4b6
40 changed files with 403 additions and 139 deletions

View File

@@ -19,7 +19,7 @@
}
@inline(__always)
@_alwaysEmitIntoClient
@export(implementation)
deinit {
buffer.deinitialize().deallocate()
}

View File

@@ -25,7 +25,7 @@ private func implicitlyInlinablePrivate() {
localInternalFunc()
}
@_neverEmitIntoClient
@export(interface)
public func explicitNonInliable() {
_ = StructFromDirect()
@@ -33,7 +33,7 @@ public func explicitNonInliable() {
_ = StructFromDirect()
}
@_neverEmitIntoClient
@export(interface)
func nested() {
_ = StructFromDirect()
}
@@ -42,7 +42,7 @@ public func explicitNonInliable() {
localInternalFunc()
}
@_alwaysEmitIntoClient
@export(implementation)
public func legalAccessToIndirect() {
_ = StructFromIndirect()
@@ -57,7 +57,7 @@ public func legalAccessToIndirect() {
}
extension Array {
@_alwaysEmitIntoClient
@export(implementation)
public var myMutableSpan: Int {
get {
return 0

View File

@@ -21,7 +21,7 @@
//--- Library.swift
// LIBRARY-IR: define {{(protected |dllexport )?}}swiftcc ptr @"$e7Library5helloSaySiGyF"()
@_neverEmitIntoClient
@export(interface)
public func hello() -> [Int] {
getArray()
}
@@ -52,7 +52,7 @@ public func unnecessary() -> Int { 5 }
//--- Application.swift
import Library
@_neverEmitIntoClient
@export(interface)
public func testMe() {
_ = hello()
_ = getArray()
@@ -64,8 +64,8 @@ public func testMe() {
// APPLICATION-SIL: sil @$e7Library5helloSaySiGyF : $@convention(thin) () -> @owned Array<Int>{{$}}
// APPLICATION-IR: declare swiftcc ptr @"$e7Library5helloSaySiGyF"()
// Note: "getArray" is not @_neverEmitIntoClient, so it's definition is
// available.
// Note: "getArray" is not prohibited from being emitted into the client, so
// its definition is available.
// APPLICATION-SIL: sil public_external @$e7Library8getArraySaySiGyF : $@convention(thin) () -> @owned Array<Int> {
// APPLICATION-IR: define linkonce_odr hidden swiftcc ptr @"$e7Library8getArraySaySiGyF"()

View File

@@ -28,7 +28,7 @@
// RUN: rm -rf %t/Dependencies
// Build the application against the library. This is expected to work because
// @_neverEmitIntoClient hides the body of test().
// @export(interface) hides the body of test().
// RUN: %target-swift-frontend -emit-ir -parse-as-library %t/Files/Application.swift -enable-experimental-feature Embedded -I %t/Modules -o %t/Application.ir
// REQUIRES: swift_in_compiler
@@ -38,7 +38,7 @@
@_implementationOnly import CDependency // expected-warning {{using '@_implementationOnly' without enabling library evolution for 'Library' may lead to instability during execution}}
@_implementationOnly import SwiftDependency // expected-warning {{using '@_implementationOnly' without enabling library evolution for 'Library' may lead to instability during execution}}
@_neverEmitIntoClient
@export(interface)
public func test() {
_ = getPoint(3.14159, 2.71828)
A().doSomething()
@@ -46,13 +46,13 @@ public func test() {
#if BAD_IOI_USAGE
public func badCLibraryUsage() {
_ = getPoint(3.14159, 2.71828) // expected-error {{global function 'getPoint' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'CDependency' was imported implementation-only}}
_ = getPoint(3.14159, 2.71828) // expected-error {{global function 'getPoint' cannot be used in an embedded function not marked '@export(interface)' because 'CDependency' was imported implementation-only}}
}
public func badSwiftLibraryUsage() {
A().doSomething() // expected-error {{struct 'A' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'SwiftDependency' was imported implementation-only}}
// expected-error @-1 {{initializer 'init()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'SwiftDependency' was imported implementation-only}}
// expected-error @-2 {{instance method 'doSomething()' cannot be used in an embedded function not marked '@_neverEmitIntoClient' because 'SwiftDependency' was imported implementation-only}}
A().doSomething() // expected-error {{struct 'A' cannot be used in an embedded function not marked '@export(interface)' because 'SwiftDependency' was imported implementation-only}}
// expected-error @-1 {{initializer 'init()' cannot be used in an embedded function not marked '@export(interface)' because 'SwiftDependency' was imported implementation-only}}
// expected-error @-2 {{instance method 'doSomething()' cannot be used in an embedded function not marked '@export(interface)' because 'SwiftDependency' was imported implementation-only}}
}
#endif

View File

@@ -53,7 +53,7 @@ private func throughPrivate() -> [Int] {
public func unnecessary() -> Int64 { 5 }
// LIBRARY-IR: define {{.*}} @"$e7Library14unusedYetThere
@_neverEmitIntoClient
@export(interface)
public func unusedYetThere() -> Int64 { 5 }
open class PointClass {
@@ -81,7 +81,7 @@ extension PointClass: Reflectable {
}
// LIBRARY-IR: define {{.*}} @"$e7Library18createsExistentialAA11Reflectable_pyF"()
@_neverEmitIntoClient
@export(interface)
public func createsExistential() -> any Reflectable {
return PointClass(x: 5, y: 5)
}