> On Jun 13, 2017, at 16:11, John McCall via swift-dev <swift-dev@swift.org> > wrote: > > 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. > > A bridging conversion 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 bridged to the foreign type. > > Bridging conversions are performed for three reasons in Swift: > > 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". > > 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. > > 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. > > 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. > > 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. > > The proposal is to apply a guaranteed syntactic "peephole" to eliminate > bridging conversions that arise from reason #3. Specifically: > > No bridging conversions will be performed if: > - a call, property reference, or subscript reference is the immediate > syntactic > operand of an "as" cast to a type compatible with the foreign return, > property, > or subscript element type or > - a call argument, right operand of an assignment to a property > reference, or > right operand of an assignment to a subscript reference is an "as" cast > from a > type compatible with the foreign parameter, property, or subscript > element type. > Two types are "compatible" if there is a simple subclass or class-protocol > relationship > between the underlying non-optional types. > > We believe that this rule is easy and intuitive enough to understand that it > will not cause substantial problems.
Thanks for writing this all down, John. Should returns also be included in this? That is: override func someObjCFunction() -> String { return NSMutableString() as String } (and, having written that, it seems useful to show code examples for each of your cases.) Jordan
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev