[swift-dev] Casting shadow protocols
dabrahams at apple.com
Fri Nov 4 22:55:28 CDT 2016
on Fri Nov 04 2016, Slava Pestov <swift-dev-AT-swift.org> wrote:
> If the casts are always in one direction, can you make one protocol
> refine another?
Yeah, I am shocked if they don't do that already.
> Also note that @objc protocols are self-conforming as long as they
> don’t contain initializers or static methods, but I’m not sure if that
Doesn't; we're not using these in a generic context; they're just
>> On Nov 4, 2016, at 4:29 PM, Alexis via swift-dev <swift-dev at 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.
>> swift-dev mailing list
>> swift-dev at swift.org
> swift-dev mailing list
> swift-dev at swift.org
More information about the swift-dev