<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 &lt;<a href="mailto:davidhart@fastmail.com" class="">davidhart@fastmail.com</a>&gt; 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="">&nbsp; &nbsp; - a call, property reference, or subscript reference is the immediate syntactic&nbsp;</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="">&nbsp;</span><i class="" style="background-color: rgba(255, 255, 255, 0);">to</i><span style="background-color: rgba(255, 255, 255, 0);" class="">&nbsp;</span><span style="background-color: rgba(255, 255, 255, 0);" class="">a type compatible with the foreign return, property,&nbsp;</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&nbsp;FooBar {</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">func</span><span style="font-family: Menlo;" class="">&nbsp;foo() -&gt;&nbsp;</span><span style="font-family: Menlo;" class="">NSMutableArray</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">var</span><span style="font-family: Menlo;" class="">&nbsp;bar:&nbsp;</span><span style="font-family: Menlo;" class="">NSMutableDictionary</span><span style="font-family: Menlo;" class="">&nbsp;{&nbsp;</span><span style="font-family: Menlo;" class="">get</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">set</span><span style="font-family: Menlo;" class="">&nbsp;}</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;</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="">&nbsp;index:&nbsp;</span><span style="font-family: Menlo;" class="">Int</span><span style="font-family: Menlo;" class="">) -&gt;&nbsp;</span><span style="font-family: Menlo;" class="">NSDecimalNumber</span><span style="font-family: Menlo;" class="">&nbsp;{&nbsp;</span><span style="font-family: Menlo;" class="">get</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">set</span><span style="font-family: Menlo;" class="">&nbsp;}</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="">&nbsp; &nbsp; - a call argument, right operand of an assignment to a property reference, or&nbsp;</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&nbsp;</span><i class="" style="background-color: rgba(255, 255, 255, 0);">from</i><span style="background-color: rgba(255, 255, 255, 0);" class="">&nbsp;a&nbsp;</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&nbsp;BarFoo {<br class="">&nbsp; &nbsp;&nbsp;func&nbsp;foo(_&nbsp;array:&nbsp;NSArray)<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;bar:&nbsp;NSDictionary&nbsp;{&nbsp;get&nbsp;set&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;subscript(_&nbsp;index:&nbsp;Int) -&gt;&nbsp;NSNumber&nbsp;{&nbsp;get&nbsp;set&nbsp;}<br class="">}</font></div></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">var&nbsp;barfoo: BarFoo = ...<br class="">barfoo.foo(NSMutableArray()&nbsp;as&nbsp;NSArray)<br class="">barfoo.bar&nbsp;=&nbsp;NSMutableDictionary()&nbsp;as&nbsp;NSDictionary<br class="">barfoo[1] =&nbsp;NSDecimalNumber(string:&nbsp;"1.2")&nbsp;as&nbsp;NSNumber</font></div><div class=""><div class=""><br class=""><!-- signature close --></div>On 14 Jun 2017, at 01:11, John McCall via swift-dev &lt;<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>&gt; 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>&nbsp;is a conversion between a Swift type and a foreign type (C / ObjC / whatever) which can represent the same set of values. &nbsp;For example, there are bridging conversions from Swift.String to ObjC's NSString and vice-versa. &nbsp;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. &nbsp;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. &nbsp;(This is perhaps a mistake.) &nbsp; 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. &nbsp;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. &nbsp;First, they do impose some performance overhead which the user may not want. &nbsp;But they can also change semantics in unwanted ways. &nbsp;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. &nbsp;A pair of bridging conversions from NSString to String and then back to NSString is likely to lose this reference identity. &nbsp;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. &nbsp;This is unsatisfactory. &nbsp;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. &nbsp;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. &nbsp;Specifically:</div><div class=""><br class=""></div><div class="">&nbsp; No bridging conversions will be performed if:</div><div class="">&nbsp; &nbsp; - a call, property reference, or subscript reference is the immediate syntactic</div><div class="">&nbsp; &nbsp; &nbsp; operand of an "as" cast <i class="">to</i> a type compatible with the foreign return, property,</div><div class="">&nbsp; &nbsp; &nbsp; or subscript element type or</div><div class="">&nbsp; &nbsp; - a call argument, right operand of an assignment to a property reference, or</div><div class="">&nbsp; &nbsp; &nbsp; right operand of an assignment to a subscript reference is an "as" cast <i class="">from</i>&nbsp;a</div><div class="">&nbsp; &nbsp; &nbsp; type compatible with the foreign parameter, property, or subscript element type.</div><div class="">&nbsp; Two types are "compatible" if there is a simple subclass or class-protocol relationship</div><div class="">&nbsp; 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>