when compiling the below example with the flags -Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks I get the warning "Cannot use property 'url' with a non-sendable type 'URL' across actors" in the init method and the test function.
Is the warning correct here? If yes, what would be the correct way to have an actor which has an URL as a property?
public actor ActorWithURL {
private let url: URL
init(url: URL) {
self.url = url
}
}
func test() {
_ = ActorWithURL(url: URL(fileURLWithPath: "https://example.com"))
}
Yep, pretty much nothing in Foundation is Sendable. That includes URL, Data, and even Date.
func needsSendable<T>(_ x: T) where T: Sendable {
print("\(x) is Sendable")
}
needsSendable(URL(string: "https://example.com/")!)
// ❌ Local function 'needsSendable' requires that 'URL' conform to 'Sendable'
needsSendable(Data(0..<5))
// ❌ Local function 'needsSendable' requires that 'Data' conform to 'Sendable'
needsSendable(Date.now)
// ❌ Local function 'needsSendable' requires that 'Date' conform to 'Sendable'
needsSendable(1.234 as Decimal)
// 🤷♂️ I don't know why this one type works and nothing else does, but there you go.
Oh, I didn't actually pass those flags when testing (I just stuck it in a unit test of a package I happened to be working on, using whatever the default settings happen to be in 5.5.2). If those flags make things even stricter, then that's an even bigger headache.
I suppose in the mean time, you'll need to add your own @unchecked Sendable conformances for anything you use from Foundation. I think that should be okay for most things (?).
Yep, I switched the flags on, to be "prepared for the future" ;-). @unchecked Sendable works, but I hope it will be not needed in the (not so distant) future, because essentially I like the idea, that the compiler double checks my concurrent coding. Also I think it is not easy to see if @unchecked Sendable is safe to use on certain Foundation types, since we do not know the underlying implementation...