> On Nov 7, 2016, at 12:15 PM, Alexis via swift-dev <swift-dev@swift.org> 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? If so, that would probably be an acceptable improvement. (the best we > could ever hope to do?)
This is what I call lying about types. _unsafeReferenceCast does not and should not support that. It *should* actually have sanity checks to catch such incorrect usage. The checks aren’t implemented yet. Instead you may end up with a crash in the runtime. unsafeBitCast is the way to lie about a type. It only works when - dealing with a @objc class protocol - we guarantee that the mistyped reference will never be dynamically cast or accessed in any way other than msgSend Those conditions make it immune from struct aliasing based on a technicality. It does encourage bad practice, and our memory model documentation now needs to make exceptions for this special, confusing case. I like JoeG’s idea of a msgSend builtin. I’m just not sure that would completely obsolete shadow protocols. Are we also using them to satisfy protocol requirements? -Andy >> On Nov 7, 2016, at 2:30 PM, Dave Abrahams <dabrah...@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@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@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@swift.org >>>>>> https://lists.swift.org/mailman/listinfo/swift-dev >>>>> >>>>> _______________________________________________ >>>>> swift-dev mailing list >>>>> swift-dev@swift.org <mailto:swift-dev@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@swift.org <mailto:swift-dev@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@swift.org > https://lists.swift.org/mailman/listinfo/swift-dev _______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev