<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=""><div><blockquote type="cite" class=""><div class="">On Jun 14, 2017, at 2:24 AM, David Hart <<a href="mailto:davidhart@fastmail.com" class="">davidhart@fastmail.com</a>> wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="auto" class=""><div class="">Very good description. It's always worth re-explaining terms like bridged conversion to make sure every body is on the same page. But concerning the rules at the end, I’m not quite sure I understood them all. Please let me know if I’m correct:</div></div></div></div></blockquote><div><br class=""></div>Yes, all of your examples should avoid bridging conversions.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="auto" class=""><div class=""><br class=""></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">No bridging conversions will be performed if:</span></div><div class=""><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> - a call, property reference, or subscript reference is the immediate syntactic </span></font><span style="background-color: rgba(255, 255, 255, 0);" class="">operand of an "as" cast</span><span style="background-color: rgba(255, 255, 255, 0);" class=""> </span><i class="" style="background-color: rgba(255, 255, 255, 0);">to</i><span style="background-color: rgba(255, 255, 255, 0);" class=""> </span><span style="background-color: rgba(255, 255, 255, 0);" class="">a type compatible with the foreign return, property, </span><span style="background-color: rgba(255, 255, 255, 0);" class="">or subscript element type</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><span style="font-family: Menlo;" class="">protocol FooBar {</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class=""> </span><span style="font-family: Menlo;" class="">func</span><span style="font-family: Menlo;" class=""> foo() -> </span><span style="font-family: Menlo;" class="">NSMutableArray</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class=""> </span><span style="font-family: Menlo;" class="">var</span><span style="font-family: Menlo;" class=""> bar: </span><span style="font-family: Menlo;" class="">NSMutableDictionary</span><span style="font-family: Menlo;" class=""> { </span><span style="font-family: Menlo;" class="">get</span><span style="font-family: Menlo;" class=""> </span><span style="font-family: Menlo;" class="">set</span><span style="font-family: Menlo;" class=""> }</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class=""> </span><span style="font-family: Menlo;" class="">subscript</span><span style="font-family: Menlo;" class="">(</span><span style="font-family: Menlo;" class="">_</span><span style="font-family: Menlo;" class=""> index: </span><span style="font-family: Menlo;" class="">Int</span><span style="font-family: Menlo;" class="">) -> </span><span style="font-family: Menlo;" class="">NSDecimalNumber</span><span style="font-family: Menlo;" class=""> { </span><span style="font-family: Menlo;" class="">get</span><span style="font-family: Menlo;" class=""> </span><span style="font-family: Menlo;" class="">set</span><span style="font-family: Menlo;" class=""> }</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">}</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><font face="Menlo" class="">let foobar: FooBar = ...</font></div><div class=""><font face="Menlo" class="">foobar.foo() as NSArray</font></div><div class=""><font face="Menlo" class="">foobar.bar as NSDictionary</font></div><div class=""><font face="Menlo" class="">foobar[0] as NSNumber</font></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> - a call argument, right operand of an assignment to a property reference, or </span></font><span style="background-color: rgba(255, 255, 255, 0);" class="">right operand of an assignment to a subscript reference is an "as" cast </span><i class="" style="background-color: rgba(255, 255, 255, 0);">from</i><span style="background-color: rgba(255, 255, 255, 0);" class=""> a </span><span style="background-color: rgba(255, 255, 255, 0);" class="">type compatible with the foreign parameter, property, or subscript element type.</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><font face="Menlo" class="">protocol BarFoo {<br class=""> func foo(_ array: NSArray)<br class=""> var bar: NSDictionary { get set }<br class=""> subscript(_ index: Int) -> NSNumber { get set }<br class="">}</font></div></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">var barfoo: BarFoo = ...<br class="">barfoo.foo(NSMutableArray() as NSArray)<br class="">barfoo.bar = NSMutableDictionary() as NSDictionary<br class="">barfoo[1] = NSDecimalNumber(string: "1.2") as NSNumber</font></div><div class=""><div class=""><br class=""><!-- signature close --></div>On 14 Jun 2017, at 01:11, John McCall via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" 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 class=""><br class=""></div><div class="">John.</div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-dev mailing list</span><br class=""><span class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-dev" class="">https://lists.swift.org/mailman/listinfo/swift-dev</a></span><br class=""></div></blockquote></div></div></div></blockquote></div><br class=""></body></html>