Skip to content

Commit f3a443a

Browse files
committed
Adopt @abi in the standard library
This commit enables the ABIAttribute feature in the standard library build and replaces every instance of `@_silgen_name(<mangled Swift name>)` in stdlib/public with an `@abi` attribute.
1 parent dc307da commit f3a443a

36 files changed

+408
-149
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,15 +1131,17 @@ ways to misuse it:
11311131
be reliably recovered through C interfaces like `dlsym`. If you want to
11321132
implement a plugin-style interface, use `Bundle`/`NSBundle` if available, or
11331133
export your plugin entry points as C entry points using `@_cdecl`.
1134-
1134+
- Don't use `@_silgen_name` when you need to make a change to an ABI-stable
1135+
declaration's signature that would normally alter its mangled name, but you
1136+
need to preserve the old mangled name for ABI compatibility. We used to use it
1137+
for this task, but `@abi` can do it with fewer limitations, more safety, and
1138+
better readability. If for some reason you do need `@_silgen_name`, you will
1139+
need to be careful that the change doesn't materially affect the actual
1140+
calling convention of the function in an incompatible way.
1141+
11351142
Legitimate uses may include:
11361143

11371144
- Use `@_silgen_name` if you're implementing the Swift runtime.
1138-
- Use `@_silgen_name` if you need to make a change to an ABI-stable
1139-
declaration's signature that would normally alter its mangled name, but you
1140-
need to preserve the old mangled name for ABI compatibility. You will need
1141-
to be careful that the change doesn't materially affect the actual calling
1142-
convention of the function in an incompatible way.
11431145
- Use `@_silgen_name` if certain declarations need to have predictable symbol
11441146
names, such as to be easily referenced by linker scripts or other highly
11451147
customized build environments (and it's OK for those predictable symbols to

docs/StandardLibraryProgrammersManual.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ This attribute specifies the name that a declaration will have at link time. It
455455
1. To specify the symbol name of a Swift function so that it can be called from Swift-aware C. Such functions have bodies.
456456
2. To provide a Swift declaration which really represents a C declaration. Such functions do not have bodies.
457457
458+
In the past it was sometimes used for ABI backwards compatibility hacks, but `@abi` does this job better.
459+
458460
##### Using `@_silgen_name` to call Swift from Swift-aware C
459461
460462
Rather than hard-code Swift mangling into C code, `@_silgen_name` is used to provide a stable and known symbol name for linking. Note that C code still must understand and use the Swift calling convention (available in swift-clang) for such Swift functions (if they use Swift's CC). Example:

stdlib/cmake/modules/SwiftSource.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ function(_compile_swift_files
633633
list(APPEND swift_flags "-enable-experimental-feature" "NonescapableTypes")
634634

635635
list(APPEND swift_flags "-enable-experimental-feature" "ExtensionImportVisiblity")
636+
list(APPEND swift_flags "-enable-experimental-feature" "ABIAttribute")
636637

637638
if (SWIFT_STDLIB_ENABLE_STRICT_CONCURRENCY_COMPLETE)
638639
list(APPEND swift_flags "-strict-concurrency=complete")

stdlib/public/Concurrency/AsyncStream.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,12 @@ public struct AsyncStream<Element> {
330330
/// }
331331
///
332332
///
333-
@_silgen_name("$sScS9unfolding8onCancelScSyxGxSgyYac_yyYbcSgtcfC")
333+
@abi(
334+
public init(
335+
unfolding produce: @escaping /* not @Sendable*/ () async -> Element?,
336+
onCancel: (@Sendable () -> Void)? = nil
337+
)
338+
)
334339
@preconcurrency // Original API had `@Sendable` only on `onCancel`
335340
public init(
336341
unfolding produce: @escaping @Sendable () async -> Element?,

stdlib/public/Concurrency/CheckedContinuation.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,14 @@ public func withCheckedContinuation<T>(
313313
//
314314
// This function also doubles as an ABI-compatibility shim predating the
315315
// introduction of #isolation.
316+
@abi(
317+
public func withCheckedContinuation<T>(
318+
function: String,
319+
_ body: (CheckedContinuation<T, Never>) -> Void
320+
) async -> T
321+
)
316322
@available(SwiftStdlib 5.1, *)
317323
@_unsafeInheritExecutor // ABI compatibility with Swift 5.1
318-
@_silgen_name("$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalF")
319324
public func _unsafeInheritExecutor_withCheckedContinuation<T>(
320325
function: String = #function,
321326
_ body: (CheckedContinuation<T, Never>) -> Void
@@ -377,9 +382,14 @@ public func withCheckedThrowingContinuation<T>(
377382
//
378383
// This function also doubles as an ABI-compatibility shim predating the
379384
// introduction of #isolation.
385+
@abi(
386+
public func withCheckedThrowingContinuation<T>(
387+
function: String,
388+
_ body: (CheckedContinuation<T, Error>) -> Void
389+
) async throws -> T
390+
)
380391
@available(SwiftStdlib 5.1, *)
381392
@_unsafeInheritExecutor // ABI compatibility with Swift 5.1
382-
@_silgen_name("$ss31withCheckedThrowingContinuation8function_xSS_yScCyxs5Error_pGXEtYaKlF")
383393
public func _unsafeInheritExecutor_withCheckedThrowingContinuation<T>(
384394
function: String = #function,
385395
_ body: (CheckedContinuation<T, Error>) -> Void

stdlib/public/Concurrency/DiscardingTaskGroup.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,14 @@ public func withDiscardingTaskGroup<GroupResult>(
9797
//
9898
// This function also doubles as an ABI-compatibility shim predating the
9999
// introduction of #isolation.
100+
@abi(
101+
public func withDiscardingTaskGroup<GroupResult>(
102+
returning returnType: GroupResult.Type = GroupResult.self,
103+
body: (inout DiscardingTaskGroup) async -> GroupResult
104+
) async -> GroupResult
105+
)
100106
@available(SwiftStdlib 5.9, *)
101107
@_unsafeInheritExecutor // for ABI compatibility
102-
@_silgen_name("$ss23withDiscardingTaskGroup9returning4bodyxxm_xs0bcD0VzYaXEtYalF")
103108
public func _unsafeInheritExecutor_withDiscardingTaskGroup<GroupResult>(
104109
returning returnType: GroupResult.Type = GroupResult.self,
105110
body: (inout DiscardingTaskGroup) async -> GroupResult
@@ -513,9 +518,14 @@ public func withThrowingDiscardingTaskGroup<GroupResult>(
513518
return result
514519
}
515520

521+
@abi(
522+
public func withThrowingDiscardingTaskGroup<GroupResult>(
523+
returning returnType: GroupResult.Type = GroupResult.self,
524+
body: (inout ThrowingDiscardingTaskGroup<Error>) async throws -> GroupResult
525+
) async throws -> GroupResult
526+
)
516527
@available(SwiftStdlib 5.9, *)
517528
@_unsafeInheritExecutor // for ABI compatibility
518-
@_silgen_name("$ss31withThrowingDiscardingTaskGroup9returning4bodyxxm_xs0bcdE0Vys5Error_pGzYaKXEtYaKlF")
519529
public func _unsafeInheritExecutor_withThrowingDiscardingTaskGroup<GroupResult>(
520530
returning returnType: GroupResult.Type = GroupResult.self,
521531
body: (inout ThrowingDiscardingTaskGroup<Error>) async throws -> GroupResult

stdlib/public/Concurrency/ExecutorAssertions.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,10 +368,17 @@ extension Actor {
368368
}
369369
}
370370

371+
@abi(
372+
@usableFromInline
373+
@_unavailableInEmbedded
374+
internal nonisolated func assumeIsolated<T>(
375+
_ operation: (isolated Self) throws -> T,
376+
file: StaticString, line: UInt
377+
) rethrows -> T
378+
)
371379
@available(SwiftStdlib 5.9, *)
372380
@usableFromInline
373381
@_unavailableInEmbedded
374-
@_silgen_name("$sScAsE14assumeIsolated_4file4lineqd__qd__xYiKXE_s12StaticStringVSutKlF")
375382
internal nonisolated func __abi__assumeIsolated<T : Sendable>(
376383
_ operation: (isolated Self) throws -> T,
377384
_ file: StaticString, _ line: UInt

stdlib/public/Concurrency/MainActor.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,15 @@ extension MainActor {
148148
}
149149
}
150150

151+
@abi(
152+
@usableFromInline
153+
internal static func assumeIsolated<T>(
154+
_ operation: @MainActor () throws -> T,
155+
file: StaticString, line: UInt
156+
) rethrows -> T
157+
)
151158
@available(SwiftStdlib 5.9, *)
152159
@usableFromInline
153-
@_silgen_name("$sScM14assumeIsolated_4file4linexxyKScMYcXE_s12StaticStringVSutKlFZ")
154160
internal static func __abi__assumeIsolated<T : Sendable>(
155161
_ operation: @MainActor () throws -> T,
156162
_ file: StaticString, _ line: UInt

stdlib/public/Concurrency/Task+TaskExecutor.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,16 @@ public func withTaskExecutorPreference<T, Failure>(
164164
//
165165
// This function also doubles as an ABI-compatibility shim predating the
166166
// introduction of #isolation.
167+
@abi(
168+
@_unavailableInEmbedded
169+
public func withTaskExecutorPreference<T: Sendable>(
170+
_ taskExecutor: (any TaskExecutor)?,
171+
operation: @Sendable () async throws -> T
172+
) async rethrows -> T
173+
)
167174
@_unavailableInEmbedded
168175
@available(SwiftStdlib 6.0, *)
169176
@_unsafeInheritExecutor // for ABI compatibility
170-
@_silgen_name("$ss26withTaskExecutorPreference_9operationxSch_pSg_xyYaYbKXEtYaKs8SendableRzlF")
171177
public func _unsafeInheritExecutor_withTaskExecutorPreference<T: Sendable>(
172178
_ taskExecutor: (any TaskExecutor)?,
173179
operation: @Sendable () async throws -> T

stdlib/public/Concurrency/TaskCancellation.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,14 @@ public func withTaskCancellationHandler<T>(
8989
//
9090
// This function also doubles as an ABI-compatibility shim predating the
9191
// introduction of #isolation.
92+
@abi(
93+
public func withTaskCancellationHandler<T>(
94+
operation: () async throws -> T,
95+
onCancel handler: @Sendable () -> Void
96+
) async rethrows -> T
97+
)
9298
@_unsafeInheritExecutor // ABI compatibility with Swift 5.1
9399
@available(SwiftStdlib 5.1, *)
94-
@_silgen_name("$ss27withTaskCancellationHandler9operation8onCancelxxyYaKXE_yyYbXEtYaKlF")
95100
public func _unsafeInheritExecutor_withTaskCancellationHandler<T>(
96101
operation: () async throws -> T,
97102
onCancel handler: @Sendable () -> Void

0 commit comments

Comments
 (0)