mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
* SR-14635: Casts to NSCopying should not always succeed The runtime dynamic casting logic explores a variety of strategies for each cast request. One of the last options is to wrap the source in a `__SwiftValue` box so it can bridge to Obj-C. The previous code was overly aggressive about such boxing; it performed the boxing for any source type and only checked to verify that the `__SwiftValue` box itself was compatible with the destination. Among other oddities, this results in the behavior discussed in SR-14635, where any Swift or Obj-C type will always successfully cast to NSCopying because `__SwiftValue` is compatible with NSCopying. This is actually two subtly different issues: * Class types should not be subject to `__SwiftValue` boxing at all. Casting class types to class existentials is already handled elsewhere, so this function should just reject any source with class type. * Non-class types should be boxed only when being assigned to an AnyObject (an "unconstrained class existential"). If the class existential has constraints, it is by definition a class-constrained existential which should not receive any non-class object. To solve these, this PR disables `__SwiftValue` boxing in two cases: 1. If the source is a class (reference) type. 2. If the destination has constraints Resolves SR-14635 Resolves rdar://78224322 * Avoid boxing class metatypes on Darwin But continue boxing * Non-class metatypes on all platforms * All metatypes on non-Darwin platforms Obj-C interop requires that we do not box class metatypes; those must be usable as simple pointers when passed to Obj-C. But no other metatype is object-compatible, so we have to continue boxing everything else. * Split out ObjC-specific test cases
89 KiB
89 KiB