-
Couldn't load subscription status.
- Fork 63
Description
I was once convinced that we could restrict mutation to &mut self methods, but after having battled with AppKit and seen how Swift does it, I'm beginning to doubt that this is the best way.
NSString is immutable while NSMutableString is, naturally, mutable. Since our current implementation only allows mutation of NSMutableString through &mut self, it is safe to make both of these Send + Sync; all is well and Rusty.
Now, remember that &NSMutableString -> &NSString and Id<NSMutableString, O> -> Id<NSString, O> is safe - so if we were to make mutation of NSMutableString possible through &self, not only would NSMutableString be !Sync, but so would NSString! (They could still be Send, that would simply allow moving them via. Id<T, Owned> to a different thread - quite similar to std::cell::Cell)
That's the primary downside: Our objects can no longer be shared across threads. Downsides that usually apply to Rust code (aliasing optimizations, ...) are void in our case, since NSString is already UnsafeCell.
On the other hand, if we were to remove mutability we could:
- Make
NSArray<T>,NSDictionary<K, V>and such collection types simpler - Since most frameworks use interior mutability and/or are not thread safe anyhow, the usage of the Foundation framework would match the usage of these.
- It would be possible for users to inherit
NSString, without them having to ensure that their object wasSync Id::retaincould be made safe(r?)- automatic bindings would be simpler
- Using
NSMutableStringinside adeclare_class!that is not meant to be thread-safe anyhow is easier (e.g. means we won't have to use&mutinwinit)
So... Yeah, will think about this a bit, but I think we may have to sacrifice being able to use Objective-C classes across threads (exactly the same compromise Swift does, their String is Sendable but NSString is not).