> 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