Why can't Swift infer @Sendable for this closure?

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.

2 Likes

I find another workaround:

let x = makeSourceWithBuilder {
  Just()
}

let y = x.map { }
1 Like