Skip to content

Commit 6d29ef8

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

38 files changed

+470
-192
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
@@ -637,6 +637,7 @@ function(_compile_swift_files
637637
list(APPEND swift_flags "-enable-experimental-feature" "LifetimeDependence")
638638
list(APPEND swift_flags "-enable-experimental-feature" "InoutLifetimeDependence")
639639
list(APPEND swift_flags "-enable-experimental-feature" "LifetimeDependenceMutableAccessors")
640+
list(APPEND swift_flags "-enable-experimental-feature" "ABIAttribute")
640641

641642
list(APPEND swift_flags "-enable-upcoming-feature" "MemberImportVisibility")
642643

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+
init(
335+
unfolding produce: @escaping /* not @Sendable*/ () async -> Element?,
336+
onCancel: (@Sendable () -> Void)?
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+
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+
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/Clock.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,12 @@ extension Clock {
127127
//
128128
// This function also doubles as an ABI-compatibility shim predating the
129129
// introduction of #isolation.
130+
@abi(
131+
func measure(
132+
_ work: () async throws -> Void
133+
) async rethrows -> Instant.Duration
134+
)
130135
@available(SwiftStdlib 5.7, *)
131-
@_silgen_name("$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKF")
132136
@_unsafeInheritExecutor // for ABI compatibility
133137
public func _unsafeInheritExecutor_measure(
134138
_ work: () async throws -> 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+
func withDiscardingTaskGroup<GroupResult>(
102+
returning returnType: GroupResult.Type,
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
@@ -367,9 +372,14 @@ public func withThrowingDiscardingTaskGroup<GroupResult>(
367372
return result
368373
}
369374

375+
@abi(
376+
func withThrowingDiscardingTaskGroup<GroupResult>(
377+
returning returnType: GroupResult.Type,
378+
body: (inout ThrowingDiscardingTaskGroup<Error>) async throws -> GroupResult
379+
) async throws -> GroupResult
380+
)
370381
@available(SwiftStdlib 5.9, *)
371382
@_unsafeInheritExecutor // for ABI compatibility
372-
@_silgen_name("$ss31withThrowingDiscardingTaskGroup9returning4bodyxxm_xs0bcdE0Vys5Error_pGzYaKXEtYaKlF")
373383
public func _unsafeInheritExecutor_withThrowingDiscardingTaskGroup<GroupResult>(
374384
returning returnType: GroupResult.Type = GroupResult.self,
375385
body: (inout ThrowingDiscardingTaskGroup<Error>) async throws -> GroupResult

stdlib/public/Concurrency/ExecutorAssertions.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,16 @@ extension Actor {
368368
}
369369
}
370370

371+
@abi(
372+
nonisolated func assumeIsolated<T /* not ': Sendable' */>(
373+
_ operation: (isolated Self) throws -> T,
374+
file: StaticString, line: UInt
375+
) rethrows -> T
376+
)
371377
@available(SwiftStdlib 5.9, *)
372378
@usableFromInline
373379
@_unavailableInEmbedded
374-
@_silgen_name("$sScAsE14assumeIsolated_4file4lineqd__qd__xYiKXE_s12StaticStringVSutKlF")
375-
internal nonisolated func __abi__assumeIsolated<T : Sendable>(
380+
internal nonisolated func __nonsendable_assumeIsolated<T : Sendable>(
376381
_ operation: (isolated Self) throws -> T,
377382
_ file: StaticString, _ line: UInt
378383
) rethrows -> T {

stdlib/public/Concurrency/MainActor.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,15 @@ extension MainActor {
152152
}
153153
}
154154

155+
@abi(
156+
static func assumeIsolated<T /* not ': Sendable' */>(
157+
_ operation: @MainActor () throws -> T,
158+
file: StaticString, line: UInt
159+
) rethrows -> T
160+
)
155161
@available(SwiftStdlib 5.9, *)
156162
@usableFromInline
157-
@_silgen_name("$sScM14assumeIsolated_4file4linexxyKScMYcXE_s12StaticStringVSutKlFZ")
158-
internal static func __abi__assumeIsolated<T : Sendable>(
163+
internal static func __nonsendable_assumeIsolated<T : Sendable>(
159164
_ operation: @MainActor () throws -> T,
160165
_ file: StaticString, _ line: UInt
161166
) rethrows -> T {

stdlib/public/Concurrency/Task+TaskExecutor.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,15 @@ 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+
func withTaskExecutorPreference<T: Sendable>(
169+
_ taskExecutor: (any TaskExecutor)?,
170+
operation: @Sendable () async throws -> T
171+
) async rethrows -> T
172+
)
167173
@_unavailableInEmbedded
168174
@available(SwiftStdlib 6.0, *)
169175
@_unsafeInheritExecutor // for ABI compatibility
170-
@_silgen_name("$ss26withTaskExecutorPreference_9operationxSch_pSg_xyYaYbKXEtYaKs8SendableRzlF")
171176
public func _unsafeInheritExecutor_withTaskExecutorPreference<T: Sendable>(
172177
_ taskExecutor: (any TaskExecutor)?,
173178
operation: @Sendable () async throws -> T

0 commit comments

Comments
 (0)