@@ -217,7 +217,74 @@ func class_existential_is_class(_ p: ClassBound) -> Bool {
217
217
}
218
218
219
219
// CHECK-LABEL: sil hidden @$S13generic_casts27optional_anyobject_to_classyAA1CCSgyXlSgF
220
- // CHECK: checked_cast_br {{%.*}} : $AnyObject to $C
221
220
func optional_anyobject_to_class( _ p: AnyObject ? ) -> C ? {
222
221
return p as? C
222
+ // CHECK: checked_cast_br {{%.*}} : $AnyObject to $C
223
223
}
224
+
225
+ // The below tests are to ensure we don't dig into an optional operand when
226
+ // casting to a non-class archetype, as it could dynamically be an optional type.
227
+
228
+ // CHECK-LABEL: sil hidden @$S13generic_casts32optional_any_to_opaque_archetype{{[_0-9a-zA-Z]*}}F
229
+ func optional_any_to_opaque_archetype< T> ( _ x: Any ? ) -> T {
230
+ return x as! T
231
+ // CHECK: bb0([[RET:%.*]] : @trivial $*T, {{%.*}} : @trivial $*Optional<Any>):
232
+ // CHECK: unconditional_checked_cast_addr Optional<Any> in {{%.*}} : $*Optional<Any> to T in [[RET]] : $*T
233
+ }
234
+
235
+ // CHECK-LABEL: sil hidden @$S13generic_casts46optional_any_conditionally_to_opaque_archetype{{[_0-9a-zA-Z]*}}F
236
+ func optional_any_conditionally_to_opaque_archetype< T> ( _ x: Any ? ) -> T ? {
237
+ return x as? T
238
+ // CHECK: checked_cast_addr_br take_always Optional<Any> in {{%.*}} : $*Optional<Any> to T in {{%.*}} : $*T
239
+ }
240
+
241
+ // CHECK-LABEL: sil hidden @$S13generic_casts32optional_any_is_opaque_archetype{{[_0-9a-zA-Z]*}}F
242
+ func optional_any_is_opaque_archetype< T> ( _ x: Any ? , _: T ) -> Bool {
243
+ return x is T
244
+ // CHECK: checked_cast_addr_br take_always Optional<Any> in {{%.*}} : $*Optional<Any> to T in {{%.*}} : $*T
245
+ }
246
+
247
+ // But we can dig into at most one layer of the operand if it's
248
+ // an optional archetype...
249
+
250
+ // CHECK-LABEL: sil hidden @$S13generic_casts016optional_any_to_C17_opaque_archetype{{[_0-9a-zA-Z]*}}F
251
+ func optional_any_to_optional_opaque_archetype< T> ( _ x: Any ? ) -> T ? {
252
+ return x as! T ?
253
+ // CHECK: unconditional_checked_cast_addr Any in {{%.*}} : $*Any to T in {{%.*}} : $*T
254
+ }
255
+
256
+ // CHECK-LABEL: sil hidden @$S13generic_casts030optional_any_conditionally_to_C17_opaque_archetype{{[_0-9a-zA-Z]*}}F
257
+ func optional_any_conditionally_to_optional_opaque_archetype< T> ( _ x: Any ? ) -> T ? ? {
258
+ return x as? T ?
259
+ // CHECK: checked_cast_addr_br take_always Any in {{%.*}} : $*Any to T in {{%.*}} : $*T
260
+ }
261
+
262
+ // CHECK-LABEL: sil hidden @$S13generic_casts016optional_any_is_C17_opaque_archetype{{[_0-9a-zA-Z]*}}F
263
+ func optional_any_is_optional_opaque_archetype< T> ( _ x: Any ? , _: T ) -> Bool {
264
+ return x is T ?
265
+ // Because the levels of optional are the same, 'is' doesn't transform into an 'as?',
266
+ // so we just cast directly without digging into the optional operand.
267
+ // CHECK: checked_cast_addr_br take_always Optional<Any> in {{%.*}} : $*Optional<Any> to Optional<T> in {{%.*}} : $*Optional<T>
268
+ }
269
+
270
+ // And we can dig into the operand when casting to a class archetype, as it
271
+ // cannot dynamically be optional...
272
+
273
+ // CHECK-LABEL: sil hidden @$S13generic_casts31optional_any_to_class_archetype{{[_0-9a-zA-Z]*}}F
274
+ func optional_any_to_class_archetype< T : AnyObject > ( _ x: Any ? ) -> T {
275
+ return x as! T
276
+ // CHECK: unconditional_checked_cast_addr Any in {{%.*}} : $*Any to T in {{%.*}} : $*T
277
+ }
278
+
279
+ // CHECK-LABEL: sil hidden @$S13generic_casts45optional_any_conditionally_to_class_archetype{{[_0-9a-zA-Z]*}}F
280
+ func optional_any_conditionally_to_class_archetype< T : AnyObject > ( _ x: Any ? ) -> T ? {
281
+ return x as? T
282
+ // CHECK: checked_cast_addr_br take_always Any in {{%.*}} : $*Any to T in {{%.*}} : $*T
283
+ }
284
+
285
+ // CHECK-LABEL: sil hidden @$S13generic_casts31optional_any_is_class_archetype{{[_0-9a-zA-Z]*}}F
286
+ func optional_any_is_class_archetype< T : AnyObject > ( _ x: Any ? , _: T ) -> Bool {
287
+ return x is T
288
+ // CHECK: checked_cast_addr_br take_always Any in {{%.*}} : $*Any to T in {{%.*}} : $*T
289
+ }
290
+
0 commit comments