what an awful hack!

extension KeyPath:@unchecked Sendable

it seems this was noticed nearly two years ago, and yet nothing has been done about it.

i guess this has something to do with keypaths capturing accessor parameters, and we have no way of representing the sendability of those parameters in KeyPath’s type signature. but what could we possibly use besides a KeyPath to do keypath things? (except for… escaping closures…?)

do we need SendableKeyPath, that can only capture Sendable accessor parameters?


Hmm, maybe a key path literal that only captures Sendable accessor parameters could return a type: KeyPath & Sendable?

1 Like

As the bug report notes, KeyPaths should be Sendable, and captures should already be restricted to Sendable values.

SE-0302 - Sendable and @Sendable closures:

Key path literals

Key paths themselves conform to the Sendable protocol. However, to ensure that it is safe to share key paths, key path literals can only capture values of types that conform to the Sendable protocol. This affects uses of subscripts in key paths:

class SomeClass: Hashable {
  var value: Int

class SomeContainer {
  var dict: [SomeClass : String]

let sc = SomeClass(...)

// error: capture of 'sc' in key path requires 'SomeClass' to conform
// to 'Sendable'
let keyPath = \SomeContainer.dict[sc]

But apparently that hasn't been implemented. That snippet doesn't produce the expected error.

There was some discussion about loosening this, and having sendable keypath literals produce KeyPath & Sendable, but AFAICT that never made it in to a proposal.


With -strict-concurrency=complete, I get:

t.swift:20:36: warning: cannot form key path that captures non-sendable type 'SomeClass'
  let keyPath = \SomeContainer.dict[sc]

Right. I continue to think this is the right way forward, because the currently set of restrictions makes it impossible to form key paths to actor-isolated state.



Lifting the unconditional Sendable restriction on key-path literals and instead inferring Sendable based on captures has been pitched at [Pitch] Inferring @Sendable for methods and key path literals