Skip to content

[Concurrency] Allow ~Copyable return types in TaskLocal.withValue - #92497

Draft
ktoso wants to merge 1 commit into
swiftlang:mainfrom
ktoso:wip-tasklocal-noncopyable
Draft

ktoso wants to merge 1 commit into
swiftlang:mainfrom
ktoso:wip-tasklocal-noncopyable

Conversation

@ktoso

@ktoso ktoso commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Allow a ~Copyable return type to be used inTaskLocal.withValue.

@ktoso

ktoso commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

@swift-ci please smoke test

@ktoso ktoso added the concurrency Feature: umbrella label for concurrency language features label Sep 22, 2026
Permit the operation-closure return type `R` of `TaskLocal.withValue` to be
noncopyable, matching the treatment already adopted by withTaskCancellationHandler,
withDeadline, withSerialExecutor and withContinuation.

ABI is preserved by treating the two kinds of overload differently:

- The async `nonisolated(nonsending)` withValue and the internal withValueImpl are
  `@export(implementation)` (always emitted into the client, no exported symbol), so
  their return type is relaxed to `<R: ~Copyable>` in place; the async `@abi(...)`
  shadow is relaxed to match (it exists only to avoid a mangling collision with the
  legacy @_unsafeInheritExecutor declaration and emits no symbol either).

- The synchronous withValue is `@inlinable` and has a real ABI symbol. A Copyable and
  a ~Copyable generic parameter have distinct calling conventions, so it cannot be
  relaxed in place. The public entry point becomes an `@export(implementation)`
  `withValue<R: ~Copyable>` (carrying the documentation); the original Copyable
  declaration is demoted to an internal `__abi_withValue` shim whose `@abi(...)` pins
  the original `withValue` mangling, so the existing ABI symbol keeps being emitted
  while the source name stays out of overload resolution (mirroring the existing
  __abi_get / get idiom in this file).

The deprecated isolation:-taking overload and the _unsafeInheritExecutor_ /
silgen_name shims remain copyable-only, preserving their frozen ABI.

Noncopyable-return coverage (sync, async, throwing async) is added to
test/Concurrency/Runtime/async_task_locals_basic.swift.
@ktoso
ktoso force-pushed the wip-tasklocal-noncopyable branch from 4c73b75 to 9d35701 Compare September 23, 2026 03:37
// legacy @_unsafeInheritExecutor declaration.
@abi(
nonisolated(nonsending) func withValueNonisolatedNonsending<R>(
nonisolated(nonsending) func withValueNonisolatedNonsending<R: ~Copyable>(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks weird but is right; its an impl exported func so this isnt abi change

@ktoso

ktoso commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

@swift-ci please smoke test

@ktoso
ktoso marked this pull request as draft September 23, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

concurrency Feature: umbrella label for concurrency language features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant