@@ -10,12 +10,24 @@ class Base {}
1010
1111class Sub : Base {}
1212
13+ struct Bool {
14+ var value : Builtin.Int1
15+ }
16+
1317protocol P {}
1418
1519protocol PClass : AnyObject {}
1620
1721protocol PBase : Base {}
1822
23+ public protocol Hashable {}
24+
25+ public struct AnyHashable: Hashable {
26+ internal var base: Any
27+
28+ public init<H: Hashable>(_ base: H)
29+ }
30+
1931// Test dynamic casts that preserve ownership. See DynamicCasts.cpp
2032// swift::doesCastPreserveOwnershipForTypes.
2133//
@@ -24,6 +36,7 @@ protocol PBase : Base {}
2436// (A) one type is a bridged value and the other is an object:
2537// (A1) Boxing: <trivial> as! Object
2638// (A2) Unboxing: Object as! <trivial>
39+ // (A3) Class-bridging: Error as! NSError
2740//
2841// (B) one type is transparently wrapped in __SwiftValue, while the other is
2942// unwrapped. Given:
@@ -270,33 +283,46 @@ bb0(%0 : @owned $T):
270283}
271284
272285// =============================================================================
273- // (B1) Wrapped casts - may forward through a wrapper object
274- //
275- // Note: the AnyHashable-to-AnyObject cases are currently covered
276- // by the potentially bridged casts.
286+ // (A3) Class bridging
277287
278- // TODO: The compiler could recognize this case as forwarded. Casting
279- // *from* a class to AnyObject will not wrap the class.
288+ // Casting to NSError is indirect since it may conform to Error and
289+ // require Error-to-NSError bridging, unless we can statically see
290+ // that the source type inherits NSError.
291+ //
292+ // A class-constrained archetype may be bound to NSError, unless it has a
293+ // non-NSError superclass constraint. Casts to archetypes thus must always be
294+ // indirect.
280295//
281- // CHECK-LABEL: @testClassToClassArchetypeIsWrapped
296+ // CHECK-LABEL: @testClassToClassArchetypeIsBridged
282297// CHECK: RESULT #0: 0 = 0
283298// CHECK: RESULT #1: 1 = 1
284- sil [ossa] @testClassToClassArchetypeIsWrapped : $@convention(thin) <U : AnyObject>(@owned Base) -> @owned U {
299+ sil [ossa] @testClassToClassArchetypeIsBridged : $@convention(thin) <U : AnyObject>(@owned Base) -> @owned U {
285300bb0(%0 : @owned $Base):
286301 %1 = unconditional_checked_cast %0 : $Base to U
287302 return %1 : $U
288303}
289304
290305// =============================================================================
291- // (B2) Wrapped casts - may forward through a wrapper object
306+ // (B1) __SwiftValue Wrapping
292307//
293- // Note: (B1) the AnyHashable-to-AnyObject cases are currently covered
294- // by the potentially bridged casts.
308+ // Note: the AnyHashable-to-AnyObject cases are currently covered by
309+ // the same logic that checks for potentially bridged casts. We
310+ // include it here for completeness.
311+
312+ // CHECK-LABEL: @testNonClassToClassArchetypeIsWrapped
313+ // CHECK: RESULT #0: 0 = 0
314+ // CHECK: RESULT #1: 1 = 1
315+ sil [ossa] @testNonClassToClassArchetypeIsWrapped : $@convention(thin) <U : AnyObject>(@owned AnyHashable) -> @owned U {
316+ bb0(%0 : @owned $AnyHashable):
317+ %1 = unconditional_checked_cast %0 : $AnyHashable to U
318+ return %1 : $U
319+ }
320+
321+ // =============================================================================
322+ // (B2) __SwiftValue Unwrapping
295323//
296324// TODO: In the future, when the runtime stops wrapping nontrivial types inside
297- // __SwiftValue, cases (B1) and (B2) above will no longer apply. At that time,
298- // expand ownership preserving cast types to AnyObject. Then remove the
299- // isPotentiallyAnyObject() check.
325+ // __SwiftValue, cases (B1) and (B2) will no longer apply.
300326
301327// CHECK-LABEL: @testAnyObjectToClassIsWrapped
302328// CHECK: RESULT #0: 0 = 0
@@ -310,9 +336,9 @@ bb0(%0 : @owned $AnyObject):
310336// CHECK-LABEL: @testClassArchetypeToClassIsWrapped
311337// CHECK: RESULT #0: 0 = 0
312338// CHECK: RESULT #1: 1 = 1
313- sil [ossa] @testClassArchetypeToClassIsWrapped : $@convention(thin) <U : AnyObject>(@owned U ) -> @owned Sub {
314- bb0(%0 : @owned $U ):
315- %1 = unconditional_checked_cast %0 : $U to Sub
339+ sil [ossa] @testClassArchetypeToClassIsWrapped : $@convention(thin) <T : AnyObject>(@owned T ) -> @owned Sub {
340+ bb0(%0 : @owned $T ):
341+ %1 = unconditional_checked_cast %0 : $T to Sub
316342 return %1 : $Sub
317343}
318344
@@ -402,3 +428,12 @@ bb0(%0 : @owned $Base):
402428 %1 = unconditional_checked_cast %0 : $Base to Sub
403429 return %1 : $Sub
404430}
431+
432+ // CHECK-LABEL: @testClassToAnyObjectIsForwarded
433+ // CHECK: RESULT #0: 0 = 0
434+ // CHECK: RESULT #1: 1 = 0
435+ sil [ossa] @testClassToAnyObjectIsForwarded : $@convention(thin) (@owned Base) -> @owned AnyObject {
436+ bb0(%0 : @owned $Base):
437+ %1 = unconditional_checked_cast %0 : $Base to AnyObject
438+ return %1 : $AnyObject
439+ }
0 commit comments