[swift-dev] Casting shadow protocols
Dave Abrahams
dabrahams at apple.com
Mon Nov 7 14:24:22 CST 2016
on Mon Nov 07 2016, Alexis <abeingessner-AT-apple.com> wrote:
> Does _unsafeReferenceCast at least verify that the types in question
> could theoretically be cast into each other? That is, one is derived
> from the other?
Not IIRC
> If so, that would probably be an acceptable improvement. (the best we
> could ever hope to do?)
It might be, if that's the only way it's being used.
>> On Nov 7, 2016, at 2:30 PM, Dave Abrahams <dabrahams at apple.com> wrote:
>>
>>
>> on Mon Nov 07 2016, Alexis <abeingessner-AT-apple.com> wrote:
>>
>>>> On Nov 4, 2016, at 11:55 PM, Dave Abrahams via swift-dev <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.
>>
>> Right. Then you need type punning without any dynamic checks,
>> a.k.a. _unsafeReferenceCast
>>
>>>
>>>>
>>>>> 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> 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
>>>>>> 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>
>>
>> --
>> -Dave
--
-Dave
More information about the swift-dev
mailing list