> On Nov 4, 2016, at 4:29 PM, Alexis via swift-dev <swift-dev@swift.org> wrote:
> 
> The swift standard library has this nasty little pattern/problem in it:
> 
> The types in the core library want to know about several types defined in 
> foundation: NSString, NSArray, NSDictionary, etc. But core is imported by 
> Foundation, so it can’t (circular references between modules). Thankfully, 
> everything in ObjC is pretty opaquely defined and uniform, and Swift knows 
> how to hook into that uniform layout. So the core library defines Shadow 
> Protocols which provide whatever subset of that type’s API is considered 
> interesting. These protocols are then used in place of the ObjC types. 
> There’s also some magic compiler hooks so core lib types can subclass those 
> foundation types.
> 
> However there’s sometimes two Shadow Protocols: one that defines the APIs the 
> stdlib should provide (_NSFooCore), and one that extends that with extra APIs 
> the stdlib wants to consume (_NSFoo). This leads to an awkward situation: as 
> far as the runtime is concerned, the stdlib’s _NSFooCores don’t conform to 
> _NSFoo! We know they do because it’s all just a big lie to hook into ObjC 
> message passing with a bit of type safety, but the runtime doesn’t. So if you 
> try to do a safe type cast, it will fail. This leads to a situation where we 
> sprinkle code with unsafeBitCast’s to _NSFoo which is a massive refactoring 
> hazard.
> 
> For instance, there was a struct-containing-a-class that was being cast to 
> _NSFoo in HashedCollections. This happened to work (but was probably still a 
> violation of strict aliasing?) because the struct’s only field was the class. 
> However the struct was later changed to a class, which silently made the cast 
> completely incorrect, banishing the real _NSFoo to the shadow (protocol) 
> realm.
> 
> Can we do anything better here? Note that there’s a few places where we also 
> cast an AnyObject into an _NSFoo, but there’s some chance this is all legacy 
> junk that can be updated to at least use _NSFooCore, if not _NSFoo itself.

The casting is largely just to get the compiler to let you call ObjC methods on 
an object reference, right? We could sidestep the undefined-ness of 
unsafeBitCast perhaps by just giving the standard library a 
`Builtin.objc_msgSend` that takes a selector and a bag of arguments, and 
performs the method call with ObjC method semantics.

-Joe

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to