@@ -10,12 +10,24 @@ class Base {}
10
10
11
11
class Sub : Base {}
12
12
13
+ struct Bool {
14
+ var value : Builtin.Int1
15
+ }
16
+
13
17
protocol P {}
14
18
15
19
protocol PClass : AnyObject {}
16
20
17
21
protocol PBase : Base {}
18
22
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
+
19
31
// Test dynamic casts that preserve ownership. See DynamicCasts.cpp
20
32
// swift::doesCastPreserveOwnershipForTypes.
21
33
//
@@ -24,6 +36,7 @@ protocol PBase : Base {}
24
36
// (A) one type is a bridged value and the other is an object:
25
37
// (A1) Boxing: <trivial> as! Object
26
38
// (A2) Unboxing: Object as! <trivial>
39
+ // (A3) Class-bridging: Error as! NSError
27
40
//
28
41
// (B) one type is transparently wrapped in __SwiftValue, while the other is
29
42
// unwrapped. Given:
@@ -270,33 +283,46 @@ bb0(%0 : @owned $T):
270
283
}
271
284
272
285
// =============================================================================
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
277
287
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.
280
295
//
281
- // CHECK-LABEL: @testClassToClassArchetypeIsWrapped
296
+ // CHECK-LABEL: @testClassToClassArchetypeIsBridged
282
297
// CHECK: RESULT #0: 0 = 0
283
298
// 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 {
285
300
bb0(%0 : @owned $Base):
286
301
%1 = unconditional_checked_cast %0 : $Base to U
287
302
return %1 : $U
288
303
}
289
304
290
305
// =============================================================================
291
- // (B2) Wrapped casts - may forward through a wrapper object
306
+ // (B1) __SwiftValue Wrapping
292
307
//
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
295
323
//
296
324
// 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.
300
326
301
327
// CHECK-LABEL: @testAnyObjectToClassIsWrapped
302
328
// CHECK: RESULT #0: 0 = 0
@@ -310,9 +336,9 @@ bb0(%0 : @owned $AnyObject):
310
336
// CHECK-LABEL: @testClassArchetypeToClassIsWrapped
311
337
// CHECK: RESULT #0: 0 = 0
312
338
// 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
316
342
return %1 : $Sub
317
343
}
318
344
@@ -402,3 +428,12 @@ bb0(%0 : @owned $Base):
402
428
%1 = unconditional_checked_cast %0 : $Base to Sub
403
429
return %1 : $Sub
404
430
}
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