<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="" applecontenteditable="true"><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 20, 2017, at 18:25, Michael Ilseman <<a href="mailto:milseman@apple.com" class="">milseman@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><div class=""><br class="Apple-interchange-newline">On Apr 20, 2017, at 4:55 PM, Jordan Rose via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" applecontenteditable="true" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">TLDR: Should we just always import C/ObjC types under their Swift 4 names, and use typealiases in Swift 3 mode?</div><div class=""><br class=""></div><div class="">---</div><div class=""><br class=""></div>Hi, swift-dev. As my recent PRs have probably indicated, I've been working on the problems that can come up when mixing Swift 3 and Swift 4 code. Most of these problems have to do with C/ObjC APIs that might present themselves differently in Swift 3 and Swift 4, using the "API notes" feature in our downstream branch of Clang, and a good subset of these problems have to do with<span class="Apple-converted-space"> </span><b class="">types getting renamed</b>. (This includes being "renamed" into a member, such as NSNotificationName becoming (NS)Notification.Name in Swift.)<div class=""><br class=""></div><div class="">What's the problem? Well, there are a few. First of all, an API defined in terms of the Swift 3 name should still be callable in Swift 4. As an example, let's pretend NSNotification.Name was going to be renamed NSNotification.Identifier in Swift 4.</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="">// Swift 3 library</div><div class="">public func postTestNotification(named name: NSNotification.Name) { … }</div><div class=""><br class=""></div><div class="">// Swift 4 app</div><div class="">let id: Notification.Identifier = …</div><div class="">postTestNotification(named: id) // should work</div></blockquote><br class=""><div class="">This means the reference to "NSNotification.Name" in the library's swiftmodule needs to still be resolvable. This isn't too bad if we<span class="Apple-converted-space"> </span><b class="">leave behind a typealias</b><span class="Apple-converted-space"> </span>for 'NSNotification.Name'. I have a reasonable (but too broad) implementation at <a href="https://github.com/apple/swift/pull/8737" class="">https://github.com/apple/swift/pull/8737</a>.</div><div class=""><br class=""></div><div class="">That just leads us to another problem, though: because Swift functions can be overloaded, the symbol name includes the type, and<span class="Apple-converted-space"> </span><i class="">the type has changed.</i> The Swift 3 library exposes a symbol '_T03Lib20postTestNotificationySo14<u class="">NSNotification</u>C4<u class="">Name</u>V5named_tF', but the Swift 4 client expects '_T03Lib20postTestNotificationySo14<u class="">NSNotification</u>C10<u class="">Identifier</u>V5named_tF'.</div><div class=""><br class=""></div><div class="">My planned approach to combat this was to<span class="Apple-converted-space"> </span><b class="">use the C name of the type in the mangling</b>, producing '_T03Lib20postTestNotificationySo18<u class="">NSNotificationName</u>a5named_tF'. This is prototyped in <a href="https://github.com/apple/swift/pull/8871" class="">https://github.com/apple/swift/pull/8871</a>.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">At this point Slava pointed out I was chasing down a lot of issues when there's a much simpler solution for Swift 4: when importing types, <b class="">always use the Swift 4 name</b>, and use typealiases to handle Swift 3 compatibility. This defines both of the previous issues away, as well as any more that I just haven't thought of yet.</div><div class=""><br class=""></div><div class="">There are some downsides:</div><div class="">- We currently keep people from using Swift 4 names in Swift 3 code, and we wouldn't be able to do that, since the actual declaration of the type always needs to be available.</div></div></div></blockquote><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">I don’t know if this is an important distinction to worry about. That code will still be able to use features from Swift 4, and perhaps even Swift 4 only types (e.g. Substring from SE-0163).</div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><div class=""><div class="" applecontenteditable="true" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">- We'd probably want to tweak the "aka" printing in diagnostics to not look through these typealiases. That's not hard, though.</div><div class="">- We can't<span class="Apple-converted-space"> </span><i class="">keep</i> doing this once we have ABI stability. Hopefully framework owners aren't going to continue changing Swift names of types, but we'll probably need to implement my "C name in the mangling" plan anyway, just in case.</div><div class=""><br class=""></div></div></div></blockquote><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Would this fall under the realm of library evolution, wherein name changes should be versioned? In that case, would we need both symbols whether they came from C or not?</div></div></blockquote><br class=""></div><div>I suspect we'll end up doing my appended follow-up for this: "mangle me as if my name were ___". That doesn't cover everything the importer does, though (turning enums into structs, swift_wrapper, import-as-member, etc).</div><div><br class=""></div><div>I also hope we just don't have to deal with name changes very often in Swift-land.</div><div><br class=""></div><div>Jordan</div><br class=""></body></html>