-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Sendable
to Swift Templates
#2318
base: main
Are you sure you want to change the base?
Conversation
lgtm, but not to the tests :) |
I think this should not be merged as is. We should not unconditionally mark all Swift classes as sendable. I think this makes it possible to breaks Swift Sendability guarantees. So should at the very least be opt-in. I'm happy to be convinced that my claim above is false, but I don't think it is. This PR ought to be upgraded to use configs, like I did in #2045 so lets call it Future improvement (over
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be opt in.
@heckj s input would be very valuable here |
At the very least this PR ought to verify that the experimental sendable values flag I added is set to true if the UniFFI exported objects exported contains UniFFI exported value types in its fields.. |
Is your concern about the Rust side of things or the Swift? On the Rust side, we force all interfaces to have a |
I don't know enough internals of both languages to be able to call out what might be missing in the translation interface, but reporting to swift that a class is I'd be fine with this as an opt-in, and it called out that it means the developer consuming the rust library is responsible for enforcing single threaded access, but please - do NOT make this a default without extensive verification and tests that this is a safe consideration. |
Since I don't know sufficient details to advise in any reasonably way, I'm asking on the Swift forums - as there's developers there who I believe are familiar with these specifics and can likely better advise on what's appropriate for enabling the data-race safety expectations (from the Swift side at least, maybe also being familiar with the Rust side as well) over an FFI boundary. Forum thread: https://forums.swift.org/t/question-on-sendability-swift-6-data-race-safety-and-ffi-interfaces/76219 |
My concerns are on the Swift side. |
Furthermore I think we default to generating It is very hard for us in Uniffi to prevent users from footgunning themselves, but defaulting to Im actually unsure what happens with subclasses of Foo - Bar which adds mutable non sendable fields. |
Well "yes" but Swift’s |
Yikes... The tests ran fine with |
Thank you for your valuable feedback. I’m trying to understand your concern, so please bear with me if I’m missing something. If all mutable state in Rust must already be thread-safe (via I feel that making this opt-in could add unnecessary "complexity". While I acknowledge the existence of the That said, if someone more knowledgeable than me agrees that it should indeed be a flag, I’ll gladly add it. Sidenote: |
I see nothing in https://developer.apple.com/documentation/swift/sendable which suggests we can't use @sendable unconditionally in our implementation - it sounds exactly like Send+Sync? |
Somewhat related: maybe we should make the classes |
I thought we used open classes for test-ability - git blame should show us more. If that's true then I'd be a little torn about whether to break that, or just document that these classes should not be extended? |
Yes very much so! We can either make reference types translate into @mainactor bound actors which makes using methods on uniffi::Object work directly from UI. But it is ofc a bigger future change. |
Kinda off-topic—but also related. It’s very much in the spirit of Swift to emphasize protocols and composition over inheritance (a protocol-oriented approach). So, I think this is a really good suggestion! |
Indeed, I just thought it was worth mentioning. |
ISTM that actor types would just implement another layer of locking, which should be unnecessary as the Rust object already guarantees what actors guarantee. Use of @mainactor seems like it might make sense for a small subset of objects, but not many (ie, I don't think it would make sense for any used by Mozilla). I guess I'd be fine with allowing uniffi.toml to specify actor annotations for named objects, but I doubt the ergonomics of that would actually make sense. Stepping back though, I'd still like to understand the problem with that unchecked assertion - as I said, I believe the Rust implemented objects are such that this annotation is completely safe and appropriate (notwithstanding concerns around sub-classing, so maybe preventing that is something we should do). I'm not sure if the arguments against that are saying that the assertion is not safe to add, or whether it introduces other ergonomic (rather than correctness) issues? I also see nothing in that forum thread which gives me pause. As the last comment in that forum thread mentions, "if the Rust struct is not Sync, then the Swift class shouldn’t be Sendable.", which is my understanding of the situation. The Rust structs are Sync. |
That does appear to be true - it was added in #1975 |
My concern is that it wasn't safe to add - that asserting that everything exported as a reference type was sendable (safe to be used across various threads and executors) was valid. It looks like Records are from what I'm reading in https://forums.swift.org/t/question-on-sendability-swift-6-data-race-safety-and-ffi-interfaces/76219/7, but is not for classes with mutable stored properties. It may be that asserting the |
Right, that's my understanding too, but my assertion is that the Rust implementation of these classes meets all the requirements |
@mhammond Thanks so much for your insight and feedback! I agree with you and understand your point.
|
I personally think it should be on by default, and I'm really not even sure about the opt-out - can anyone identify when it would be harmful or a problem with that attribute having been applied? What's a use-case for opting out from this? ie, I think your patch is fine and maybe could add an opt-out later if it becomes an actual thing? |
@Sajjon I don't see how that would be possible, can you please elaborate? |
But when we’re talking about Swift 6 and all the strict concurrency, you are indeed forced to use a newer version of Xcode. So I think we’re good!
Agree - that’s exactly what I was trying to suggest with the second option here 😅:
And finally, I have to say… That font you’re using—wow 🙈 |
Hey,
This PR addresses Issue #2274 by marking all generated Uniffi classes in Swift as
@unchecked Sendable
. This change ensures compatibility with Swift 6 and allows Uniffi-generated classes to be used in concurrent contexts without triggeringSendable
-related compiler errors.The addition of
@unchecked Sendable
is backward-compatible with iOS 8.0 and above, so it should be good to go?I’ve tested and verified that my Swift packages and project now work correctly with Swift 6. Here is the generated output I’m getting:
Let me know if there’s anything I missed or if there’s anything else you’d like adjusted. Thanks!