[swift-dev] Casting shadow protocols

Dave Abrahams dabrahams at apple.com
Tue Nov 8 15:11:51 CST 2016


on Tue Nov 08 2016, Michael Gottesman <mgottesman-AT-apple.com> wrote:

>> On Nov 7, 2016, at 11:23 AM, Alexis via swift-dev <swift-dev at swift.org> wrote:
>> 
>> 
>>> On Nov 4, 2016, at 11:55 PM, Dave Abrahams via swift-dev <swift-dev at swift.org
> <mailto:swift-dev at swift.org>> wrote:
>>> 
>
>>> 
>>> on Fri Nov 04 2016, Slava Pestov <swift-dev-AT-swift.org <http://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.
>> 
>> They do; _NSFoo: _NSFooCore
>> 
>> But the problem is that we have _NSFooCores and want _NSFoos.
>
> I am confused. Then why can't you just do an unconditional checked down cast to _NSFoo from
> _NSFooCore? That can definitely be expressed at the SIL level?

The check will fail.  There is no actual relationship between the type
and the protocol; we are just using the protocol to call some ObjC
methods without being able to see the actual type's declaration.

>
>
>> 
>>> 
>>>> 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
>>>> helps.
>>> 
>>> Doesn't; we're not using these in a generic context; they're just
>>> existentials.
>>> 
>>>> 
>>>> 
>>>>> On Nov 4, 2016, at 4:29 PM, Alexis via swift-dev <swift-dev at swift.org <mailto: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 <mailto:swift-dev at swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-dev
>>>> 
>>>> _______________________________________________
>>>> swift-dev mailing list
>>>> swift-dev at swift.org <mailto:swift-dev at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-dev <https://lists.swift.org/mailman/listinfo/swift-dev>
>>>> 
>>> 
>>> -- 
>>> -Dave
>>> 
>>> _______________________________________________
>>> swift-dev mailing list
>>> swift-dev at swift.org <mailto:swift-dev at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-dev
> <https://lists.swift.org/mailman/listinfo/swift-dev>
>> _______________________________________________
>> swift-dev mailing list
>> swift-dev at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-dev
>

-- 
-Dave


More information about the swift-dev mailing list