Hello,
We're adopting Swift 6 language mode, and going through our code base to fix errors and warnings.
We have one issue involving key paths and this thread seemed the most relevant.
We're trying to cast a PartialKeyPath to a KeyPath so it can be used to build a predicate expression, but in the process the Sendable annotation is lost.
public protocol KeyPathProviding: Sendable {
static func makeKeyPath(_ identifier: String) throws -> PartialKeyPath<Self> & Sendable
static func makeExpression<T: Sendable>(
identifier: String,
_ input: PredicateExpressions.Variable<some Any>
) throws -> any PredicateExpression<T>
}
extension KeyPathProviding where Self: Sendable {
static func makeExpression<T: Sendable>(
identifier: String,
_ input: PredicateExpressions.Variable<Self>
) throws -> any PredicateExpression<T> {
let partialKeyPath = try makeKeyPath(identifier) // 'partialKeyPath' is 'any PartialKeyPath<Self> & Sendable'
guard let keyPath = partialKeyPath as? KeyPath<Self, T> else { // 'keyPath' is 'KeyPath<Self, T>'
fatalError()
}
func buildKeyPath(_ root: some PredicateExpression<Self>) -> any PredicateExpression<T> {
// error: Type 'KeyPath<Self, T>' does not conform to the 'Sendable' protocol
PredicateExpressions.build_KeyPath(root: root, keyPath: keyPath)
}
return buildKeyPath(input)
}
}
Adding extension KeyPath: @unchecked @retroactive Sendable {} fixes the error, but does not feel approriate.
Is there a better solution to this?