Could someone please explain to me why Swift (version 6) doesn't infer @Sendable for the closure in the following example?
protocol Source: Sendable { }
struct Just: Source { }
extension Source {
func map(_ transform: @Sendable @escaping () -> Void) -> Just {
.init()
}
}
@resultBuilder
enum Builder {
static func buildBlock<S: Source>(_ s: S) -> S { s }
}
func makeSourceWithBuilder<S: Source>(@Builder _ make: () -> S) -> S {
make()
}
let x = makeSourceWithBuilder {
Just()
}.map { }
// ^ 🛑 error: converting non-Sendable function value to '@Sendable () -> Void' may introduce data races
I tested with the latest nightly build:
; /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2026-01-09-a.xctoolchain/usr/bin/swift -version
Apple Swift version 6.3-dev (LLVM d402ab9729f318e, Swift 2de856568572fc0)
Target: arm64-apple-macosx15.0
Build config: +assertions
I don't understand why Swift does not infer @Sendable for the closure, but it has something to do with the use of the resultBuilder. The following change eliminates the error:
let x = makeSourceWithBuilder {
return Just()
//^^^^^^ this prevents the resultBuilder transform and eliminates the error
}.map { }
That's not a useful workaround because I want the resultBuilder transform.
This is a tolerable workaround:
struct Wrapper: Source {
init<S: Source>(@Builder _: () -> S) { }
}
let y = Wrapper {
Just()
}.map { }
// no error this time
However it would be nice to avoid introducing the Wrapper type.