I would like to be able to cast non-copyables:
protocol P: ~Copyable {}
func castP<
From: P & ~Copyable,
To: P & ~Copyable
>(
to _: To.Type = To.self,
_ value: consuming From
) -> To? {
value as? To // error: Noncopyable types cannot be conditionally cast
}
I see this topic from a year ago: Impossible to type cast or test non-copyable existential types?
It seems this wasn’t resolved at the time. Are there any plans to address it in the near future?
Any possible workaround to cast such values?
Just to note - I found a bit dirty workaround that seems to be working properly for my cases:
private final class _SafeNonCopyableCast<T: ~Copyable> {
var value: T?
init(_ value: consuming T) {
self.value = .init(value)
}
consuming func `as`<To: ~Copyable>(_: To.Type) -> To? {
let casted = self as? _SafeNonCopyableCast<To>
return casted?.value.take()
}
}
private func safeNonCopyableCast<
From: P & ~Copyable,
To: P & ~Copyable
>(
_ from: consuming From,
to: To.Type = To.self
) -> To? {
_SafeNonCopyableCast(from).as(To.self)
}
I don't think it will work for all the types but works for the same type at least.
1 Like