How to cast Any to (any Sendable)?

Hello all,

The latest Xcode beta has added sendable requirements to continuation.yields. CBDescriptor.value in CoreBluetooth returns an Any?.

This means that my continuation that returns this value needs to somehow convert the Any? to an (any Sendable)? (the values are indeed sendable and @preconcurrency import CoreBluetooth doesn't fix this).

How can I do this?


1 Like

Of top of the head, one of these options might work:

  1. Create Sendable wrapper with disabled checks:
struct ValueWrapper: @unchecked Sendable {
    let value: Any?
  1. If possible, try creating disconnected instance from the value. yield actually expects sending, and Sendable is subset of this. For example, you this all copyable types, you can create local copy, that will be disconnected and therefore satisfy sending requirement. The downside if this is that you have to copy it, but that depends on details probably, still it is safe to assume that type that is in CBDescriptor.value that is Sendable shouldn't be expensive to copy.
1 Like

Unfortunately, this is a bit of a simplification of the code that I'm trying to get working, so it really needs to be able to let the compiler know that the type is Sendable. Otherwise, I see a large rewrite in the future. sigh

It seems that we are missing withUnsafeSendable<T, Result>(_ t: T, _ body: (T & Sendable) -> Result) -> Result for those moments when we know that the value is safe to send.

Both options do exactly that: tell compiler this is Sendable.

The difference is that with first option it only relies on developer that this is actually sendable, and second will keep compiler enforcements in place (if this option is possible though).

But @unchecked Sendable is exactly this, just in a bit different form.

Actually, I do have the ability to unwrap the wrapped value at the call site (I didn't think that I did), so I can use the wrapped version of this. whew

But I think that there might be cases where something is Sendable and you need to be able to tell the compiler this and you won't have the ability to unwrap it later. (Perhaps for example, an async sequence or something.)