<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 13, 2017, at 16:11, John McCall 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=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">So, there's a longstanding issue that we're planning to fix in Swift 4, and I want to both make sure that the plan is documented publicly and give people a chance to disagree with it.<div class=""><br class=""></div><div class="">A <b class="">bridging conversion</b> is a conversion between a Swift type and a foreign type (C / ObjC / whatever) which can represent the same set of values. For example, there are bridging conversions from Swift.String to ObjC's NSString and vice-versa. When there two-way conversions like this, we say that the Swift type is<b class=""> bridged to</b> the foreign type.</div><div class=""><br class=""></div><div class="">Bridging conversions are performed for three reasons in Swift:</div><div class=""><br class=""></div><div class="">1. You can always request a bridging conversion with an unconditional "as" cast. For example, if myString is a String, you can convert it to NSString by writing "myString as NSString".</div><div class=""><br class=""></div><div class="">2. Certain bridging conversions can be introduced as implicit conversions. (This is perhaps a mistake.) For example, CFString and NSString are considered different types, but they will implicitly convert to each other.</div><div class=""><br class=""></div><div class="">3. Bridging conversions are done "behind the scenes" when using an imported declaration that has been given a type that does not match its original type. For example, an Objective-C method that returns an NSString will be imported as returning a String; Swift will implicitly apply a bridging conversion to the true return value in order to produce the String that the type system has promised.</div><div class=""><br class=""></div><div class="">Bridging conversions are not always desirable. First, they do impose some performance overhead which the user may not want. But they can also change semantics in unwanted ways. For example, in certain rare situations, the reference identity of an NSString return value is important — maybe it's actually a persistent NSMutableString which should be modified in-place, or maybe it's a subclass which carries additional information. A pair of bridging conversions from NSString to String and then back to NSString is likely to lose this reference identity. In the current representation, String can store an NSString reference, and if the String is bridged to NSString that reference will be used as the result; however, the bridging conversion from NSString does not directly store the original NSString in the String, but instead stores the result of invoking +copy on it, in an effort to protect against the original NSString being somehow mutable.</div><div class=""><br class=""></div><div class="">Bridging conversions arising from reasons #1 and #2 are avoidable, but bridging conversions arising from reason #3 currently cannot be eliminated without major inconvenience, such as writing a stub in Objective-C. This is unsatisfactory. At the same time, it is not valid for Swift to simply eliminate pairs of bridging conversions as a matter of course, precisely because those bridging conversions can be semantically important. We do not want optimization settings to be able to affect things as important as whether a particular NSString is mutable or not.</div><div class=""><br class=""></div><div class="">The proposal is to apply a guaranteed syntactic "peephole" to eliminate bridging conversions that arise from reason #3. Specifically:</div><div class=""><br class=""></div><div class=""> No bridging conversions will be performed if:</div><div class=""> - a call, property reference, or subscript reference is the immediate syntactic</div><div class=""> operand of an "as" cast <i class="">to</i> a type compatible with the foreign return, property,</div><div class=""> or subscript element type or</div><div class=""> - a call argument, right operand of an assignment to a property reference, or</div><div class=""> right operand of an assignment to a subscript reference is an "as" cast <i class="">from</i> a</div><div class=""> type compatible with the foreign parameter, property, or subscript element type.</div><div class=""> Two types are "compatible" if there is a simple subclass or class-protocol relationship</div><div class=""> between the underlying non-optional types.</div><div class=""><br class=""></div><div class="">We believe that this rule is easy and intuitive enough to understand that it will not cause substantial problems.</div></div></div></blockquote><br class=""></div><div>Thanks for writing this all down, John. Should returns also be included in this? That is:</div><div><br class=""></div><div>override func someObjCFunction() -> String {</div><div> return NSMutableString() as String</div><div>}</div><div><br class=""></div><div>(and, having written that, it seems useful to show code examples for each of your cases.)</div><div><br class=""></div><div>Jordan</div><br class=""></body></html>