withoutActuallyEscaping incorrectly requires captured values to be Sendable or sending in a nonisolated(nonsending) context
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 70.4k
- Forks
- 10.8k
- PR merge metrics
- PR metrics pending
Description
Description
The compiler seems to get confused when a non-Sendable and non-sending value is captured and used by the withoutActuallyEscaping body closure in a nonisolated(nonsending) context, requiring both the captured value as well as the closure parameter to be Sendable or sending.
withoutActuallyEscaping is special cased in the compiler but should presumably act like a nonisolated(nonsending) function itself in this context. Without any captures in the body closure it works as expected and the closure parameter isn't required to be Sendable or sending in that case.
Reproduction
// Compile with `swiftc -swift-version 6`
final class NS {}
// same issue also occurs when using NonisolatedNonsendingByDefault instead of nonisolated(nonsending)
nonisolated(nonsending) func test(
_ nonSendable: NS,
_ operation: () async -> Void
) async {
await withoutActuallyEscaping(operation) { escapableOp in
print(nonSendable) // Sending 'nonSendable' risks causing data races
await escapableOp() // Sending 'operation' risks causing data races
}
}
Expected behavior
The snippet should compile without errors.
Environment
Tested with main-snapshot-2025-09-29:
Apple Swift version 6.3-dev (LLVM 984f3dccb13e621, Swift 2a9d858583dc912)
and Swift 6.2:
swift-driver version: 1.127.14.1 Apple Swift version 6.2.1 (swiftlang-6.2.1.1.1 clang-1700.4.1.1)
Additional information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by compiling the provided reproduction with swiftc -swift-version 6 and inspect the compiler handling for withoutActuallyEscaping and nonisolated(nonsending) closures. The work is done when the snippet compiles without errors, including the captured non-Sendable value and closure parameter.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100