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:
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 protocol FooBar { func foo() -> NSMutableArray var bar: NSMutableDictionary { get set } subscript(_ index: Int) -> NSDecimalNumber { get set } } let foobar: FooBar = ... foobar.foo() as NSArray foobar.bar as NSDictionary foobar[0] as NSNumber - 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. protocol BarFoo { func foo(_ array: NSArray) var bar: NSDictionary { get set } subscript(_ index: Int) -> NSNumber { get set } } var barfoo: BarFoo = ... barfoo.foo(NSMutableArray() as NSArray) barfoo.bar = NSMutableDictionary() as NSDictionary barfoo[1] = NSDecimalNumber(string: "1.2") as NSNumber On 14 Jun 2017, at 01:11, John McCall via swift-dev <swift-...@swift.org <mailto:swift-...@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. > > John. > _______________________________________________ > swift-dev mailing list > swift-...@swift.org <mailto:swift-...@swift.org> > https://lists.swift.org/mailman/listinfo/swift-dev > <https://lists.swift.org/mailman/listinfo/swift-dev>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution