1
- // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -emit-silgen -parse-as-library -enable-experimental-subclass-existentials %s | %FileCheck %s
1
+ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -emit-silgen -parse-as-library -enable-experimental-subclass-existentials -primary-file %s -verify | %FileCheck %s
2
+ // RUN: %target-swift-frontend -emit-ir -parse-as-library -enable-experimental-subclass-existentials -primary-file %s
3
+
4
+ // Note: we pass -verify above to ensure there are no spurious
5
+ // compiler warnings relating to casts.
2
6
3
7
protocol Q { }
4
8
5
9
class Base < T> : Q {
6
- func classSelfReturn( ) -> Self { }
7
- static func classSelfReturn( ) -> Self { }
10
+ required init ( classInit: ( ) ) { }
11
+ func classSelfReturn( ) -> Self {
12
+ return self
13
+ }
14
+ static func classSelfReturn( ) -> Self {
15
+ return self . init ( classInit: ( ) )
16
+ }
8
17
}
9
18
10
19
protocol P {
20
+ init ( protocolInit: ( ) )
11
21
func protocolSelfReturn( ) -> Self
12
22
static func protocolSelfReturn( ) -> Self
13
23
}
14
24
15
25
class Derived : Base < Int > , P {
16
- func protocolSelfReturn( ) -> Self { }
17
- static func protocolSelfReturn( ) -> Self { }
26
+ required init ( protocolInit: ( ) ) {
27
+ super. init ( classInit: ( ) )
28
+ }
29
+
30
+ required init ( classInit: ( ) ) {
31
+ super. init ( classInit: ( ) )
32
+ }
33
+
34
+ func protocolSelfReturn( ) -> Self {
35
+ return self
36
+ }
37
+ static func protocolSelfReturn( ) -> Self {
38
+ return self . init ( classInit: ( ) )
39
+ }
18
40
}
19
41
20
42
protocol R { }
@@ -128,7 +150,23 @@ func methodCalls(
128
150
// CHECK: end_borrow [[BORROW]] from %0 : $Base<Int> & P
129
151
let _: Base < Int > & P = baseAndP. protocolSelfReturn ( )
130
152
153
+ // CHECK: [[METATYPE:%.*]] = open_existential_metatype %1 : $@thick (Base<Int> & P).Type to $@thick (@opened("{{.*}}") (Base<Int> & P)).Type
154
+ // CHECK: [[METHOD:%.*]] = function_ref @_T021subclass_existentials4BaseC15classSelfReturnACyxGXDyFZ : $@convention(method) <τ_0_0> (@thick Base<τ_0_0>.Type) -> @owned Base<τ_0_0>
155
+ // CHECK: [[METATYPE_REF:%.*]] = upcast [[METATYPE]] : $@thick (@opened("{{.*}}") (Base<Int> & P)).Type to $@thick Base<Int>.Type
156
+ // CHECK: [[RESULT_REF2:%.*]] = apply [[METHOD]]<Int>([[METATYPE_REF]])
157
+ // CHECK: [[RESULT_REF:%.*]] = unchecked_ref_cast [[RESULT_REF2]] : $Base<Int> to $@opened("{{.*}}") (Base<Int> & P)
158
+ // CHECK: [[RESULT:%.*]] = init_existential_ref [[RESULT_REF]] : $@opened("{{.*}}") (Base<Int> & P) : $@opened("{{.*}}") (Base<Int> & P), $Base<Int> & P
159
+ // CHECK: destroy_value [[RESULT]]
131
160
let _: Base < Int > & P = baseAndPType. classSelfReturn ( )
161
+
162
+ // CHECK: [[METATYPE:%.*]] = open_existential_metatype %1 : $@thick (Base<Int> & P).Type to $@thick (@opened("{{.*}}") (Base<Int> & P)).Type
163
+ // CHECK: [[METHOD:%.*]] = witness_method $@opened("{{.*}}") (Base<Int> & P), #P.protocolSelfReturn!1 : <Self where Self : P> (Self.Type) -> () -> @dynamic_self Self, [[METATYPE]] : $@thick (@opened("{{.*}}") (Base<Int> & P)).Type : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> @out τ_0_0
164
+ // CHECK: [[RESULT:%.*]] = alloc_stack $@opened("{{.*}}") (Base<Int> & P)
165
+ // CHECK: apply [[METHOD]]<@opened("{{.*}}") (Base<Int> & P)>(%37, %35) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> @out τ_0_0
166
+ // CHECK: [[RESULT_REF:%.*]] = load [take] [[RESULT]] : $*@opened("{{.*}}") (Base<Int> & P)
167
+ // CHECK: [[RESULT_VALUE:%.*]] = init_existential_ref [[RESULT_REF]] : $@opened("{{.*}}") (Base<Int> & P) : $@opened("{{.*}}") (Base<Int> & P), $Base<Int> & P
168
+ // CHECK: destroy_value [[RESULT_VALUE]]
169
+ // CHECK: dealloc_stack [[RESULT]]
132
170
let _: Base < Int > & P = baseAndPType. protocolSelfReturn ( )
133
171
134
172
// Partial applications
@@ -137,10 +175,15 @@ func methodCalls(
137
175
138
176
let _: ( ) -> ( Base < Int > & P ) = baseAndPType. classSelfReturn
139
177
let _: ( ) -> ( Base < Int > & P ) = baseAndPType. protocolSelfReturn
178
+
179
+ let _: ( ) -> ( Base < Int > & P ) = baseAndPType. init ( classInit: )
180
+ let _: ( ) -> ( Base < Int > & P ) = baseAndPType. init ( protocolInit: )
181
+
182
+ // CHECK: return
183
+ // CHECK-NEXT: }
140
184
}
141
185
142
186
// CHECK-LABEL: sil hidden @_T021subclass_existentials19functionConversionsyAA1P_AA4BaseCySiGXcyc07returnsE4AndP_AaC_AFXcXpyc0feG5PTypeAA7DerivedCyc0fI0AJmyc0fI4TypeAA1R_AJXcyc0fiG1RAaM_AJXcXpyc0fiG5RTypetF : $@convention(thin) (@owned @callee_owned () -> @owned Base<Int> & P, @owned @callee_owned () -> @thick (Base<Int> & P).Type, @owned @callee_owned () -> @owned Derived, @owned @callee_owned () -> @thick Derived.Type, @owned @callee_owned () -> @owned Derived & R, @owned @callee_owned () -> @thick (Derived & R).Type) -> () {
143
-
144
187
func functionConversions(
145
188
returnsBaseAndP: @escaping ( ) -> ( Base < Int > & P ) ,
146
189
returnsBaseAndPType: @escaping ( ) -> ( Base < Int > & P ) . Type,
@@ -166,4 +209,259 @@ func functionConversions(
166
209
167
210
let _: ( ) -> P = returnsDerivedAndR
168
211
let _: ( ) -> P . Type = returnsDerivedAndRType
212
+
213
+ // CHECK: return %
214
+ // CHECK-NEXT: }
215
+ }
216
+
217
+ // CHECK-LABEL: sil hidden @_T021subclass_existentials9downcastsyAA1P_AA4BaseCySiGXc8baseAndP_AA7DerivedC7derivedAaC_AFXcXp0eF5PTypeAIm0H4TypetF : $@convention(thin) (@owned Base<Int> & P, @owned Derived, @thick (Base<Int> & P).Type, @thick Derived.Type) -> () {
218
+ func downcasts(
219
+ baseAndP: Base < Int > & P ,
220
+ derived: Derived ,
221
+ baseAndPType: ( Base < Int > & P ) . Type,
222
+ derivedType: Derived . Type ) {
223
+
224
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base<Int> & P
225
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
226
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<Int> & P to $Derived
227
+ let _ = baseAndP as? Derived
228
+
229
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base<Int> & P
230
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
231
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<Int> & P to $Derived
232
+ let _ = baseAndP as! Derived
233
+
234
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base<Int> & P
235
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
236
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<Int> & P to $Derived & R
237
+ let _ = baseAndP as? ( Derived & R )
238
+
239
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base<Int> & P
240
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
241
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<Int> & P to $Derived & R
242
+ let _ = baseAndP as! ( Derived & R )
243
+
244
+ // CHECK: checked_cast_br %3 : $@thick Derived.Type to $@thick (Derived & R).Type
245
+ let _ = derivedType as? ( Derived & R ) . Type
246
+
247
+ // CHECK: unconditional_checked_cast %3 : $@thick Derived.Type to $@thick (Derived & R).Type
248
+ let _ = derivedType as! ( Derived & R ) . Type
249
+
250
+ // CHECK: checked_cast_br %2 : $@thick (Base<Int> & P).Type to $@thick Derived.Type
251
+ let _ = baseAndPType as? Derived . Type
252
+
253
+ // CHECK: unconditional_checked_cast %2 : $@thick (Base<Int> & P).Type to $@thick Derived.Type
254
+ let _ = baseAndPType as! Derived . Type
255
+
256
+ // CHECK: checked_cast_br %2 : $@thick (Base<Int> & P).Type to $@thick (Derived & R).Type
257
+ let _ = baseAndPType as? ( Derived & R ) . Type
258
+
259
+ // CHECK: unconditional_checked_cast %2 : $@thick (Base<Int> & P).Type to $@thick (Derived & R).Type
260
+ let _ = baseAndPType as! ( Derived & R ) . Type
261
+
262
+ // CHECK: return
263
+ // CHECK-NEXT: }
264
+ }
265
+
266
+ // CHECK-LABEL: sil hidden @_T021subclass_existentials16archetypeUpcastsyq_9baseTAndP_q0_0E7IntAndPq1_7derivedtAA4BaseCyxGRb_AA1PR_AGySiGRb0_AaIR0_AA7DerivedCRb1_r2_lF : $@convention(thin) <T, BaseTAndP, BaseIntAndP, DerivedT where BaseTAndP : Base<T>, BaseTAndP : P, BaseIntAndP : Base<Int>, BaseIntAndP : P, DerivedT : Derived> (@owned BaseTAndP, @owned BaseIntAndP, @owned DerivedT) -> () {
267
+ func archetypeUpcasts< T,
268
+ BaseTAndP : Base < T > & P ,
269
+ BaseIntAndP : Base < Int > & P ,
270
+ DerivedT : Derived > (
271
+ baseTAndP: BaseTAndP ,
272
+ baseIntAndP : BaseIntAndP ,
273
+ derived : DerivedT ) {
274
+
275
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $BaseTAndP
276
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseTAndP
277
+ // CHECK-NEXT: init_existential_ref [[COPIED]] : $BaseTAndP : $BaseTAndP, $Base<T> & P
278
+ let _: Base < T > & P = baseTAndP
279
+
280
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %1 : $BaseIntAndP
281
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseIntAndP
282
+ // CHECK-NEXT: init_existential_ref [[COPIED]] : $BaseIntAndP : $BaseIntAndP, $Base<Int> & P
283
+ let _: Base < Int > & P = baseIntAndP
284
+
285
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %2 : $DerivedT
286
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $DerivedT
287
+ // CHECK-NEXT: init_existential_ref [[COPIED]] : $DerivedT : $DerivedT, $Base<Int> & P
288
+ let _: Base < Int > & P = derived
289
+
290
+ // CHECK: return
291
+ // CHECK-NEXT: }
292
+ }
293
+
294
+ // CHECK-LABEL: sil hidden @_T021subclass_existentials18archetypeDowncastsyx1s_q_1tq0_2ptq1_5baseTq2_0F3Intq3_0f6TAndP_C0q4_0fg5AndP_C0q5_08derived_C0AA1R_AA7DerivedCXc0ji2R_C0AA1P_AA4BaseCyq_GXc0fH10P_concreteAaO_AQySiGXc0fgi2P_M0tAaOR0_ARRb1_ATRb2_ARRb3_AaOR3_ATRb4_AaOR4_AMRb5_r6_lF : $@convention(thin) <S, T, PT, BaseT, BaseInt, BaseTAndP, BaseIntAndP, DerivedT where PT : P, BaseT : Base<T>, BaseInt : Base<Int>, BaseTAndP : Base<T>, BaseTAndP : P, BaseIntAndP : Base<Int>, BaseIntAndP : P, DerivedT : Derived> (@in S, @in T, @in PT, @owned BaseT, @owned BaseInt, @owned BaseTAndP, @owned BaseIntAndP, @owned DerivedT, @owned Derived & R, @owned Base<T> & P, @owned Base<Int> & P) -> () {
295
+ func archetypeDowncasts< S,
296
+ T,
297
+ PT : P ,
298
+ BaseT : Base < T > ,
299
+ BaseInt : Base < Int > ,
300
+ BaseTAndP : Base < T > & P ,
301
+ BaseIntAndP : Base < Int > & P ,
302
+ DerivedT : Derived > (
303
+ s: S ,
304
+ t: T ,
305
+ pt: PT ,
306
+ baseT : BaseT ,
307
+ baseInt : BaseInt ,
308
+
309
+ baseTAndP_archetype: BaseTAndP ,
310
+ baseIntAndP_archetype : BaseIntAndP ,
311
+ derived_archetype : DerivedT ,
312
+ derivedAndR_archetype : Derived & R ,
313
+
314
+ baseTAndP_concrete: Base < T > & P ,
315
+ baseIntAndP_concrete: Base < Int > & P ) {
316
+
317
+ // CHECK: [[COPY:%.*]] = alloc_stack $S
318
+ // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S
319
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base<T> & P
320
+ // CHECK-NEXT: checked_cast_addr_br take_always S in [[COPY]] : $*S to Base<T> & P in [[RESULT]] : $*Base<T> & P
321
+ let _ = s as? ( Base < T > & P )
322
+
323
+ // CHECK: [[COPY:%.*]] = alloc_stack $S
324
+ // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S
325
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base<T> & P
326
+ // CHECK-NEXT: unconditional_checked_cast_addr take_always S in [[COPY]] : $*S to Base<T> & P in [[RESULT]] : $*Base<T> & P
327
+ let _ = s as! ( Base < T > & P )
328
+
329
+ // CHECK: [[COPY:%.*]] = alloc_stack $S
330
+ // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S
331
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base<Int> & P
332
+ // CHECK-NEXT: checked_cast_addr_br take_always S in [[COPY]] : $*S to Base<Int> & P in [[RESULT]] : $*Base<Int> & P
333
+ let _ = s as? ( Base < Int > & P )
334
+
335
+ // CHECK: [[COPY:%.*]] = alloc_stack $S
336
+ // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S
337
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base<Int> & P
338
+ // CHECK-NEXT: unconditional_checked_cast_addr take_always S in [[COPY]] : $*S to Base<Int> & P in [[RESULT]] : $*Base<Int> & P
339
+ let _ = s as! ( Base < Int > & P )
340
+
341
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %5 : $BaseTAndP
342
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseTAndP
343
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $BaseTAndP to $Derived & R
344
+ let _ = baseTAndP_archetype as? ( Derived & R )
345
+
346
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %5 : $BaseTAndP
347
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseTAndP
348
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $BaseTAndP to $Derived & R
349
+ let _ = baseTAndP_archetype as! ( Derived & R )
350
+
351
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
352
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
353
+ // CHECK-NEXT: [[COPY:%.*]] = alloc_stack $Base<T> & P
354
+ // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base<T> & P
355
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Optional<S>
356
+ // CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[RESULT]] : $*Optional<S>, #Optional.some
357
+ // CHECK-NEXT: checked_cast_addr_br take_always Base<T> & P in [[COPY]] : $*Base<T> & P to S in [[PAYLOAD]] : $*S
358
+ let _ = baseTAndP_concrete as? S
359
+
360
+ // CHECK: [[COPY:%.*]] = alloc_stack $Base<T> & P
361
+ // CHECK-NEXT: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
362
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
363
+ // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base<T> & P
364
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $S
365
+ // CHECK-NEXT: unconditional_checked_cast_addr take_always Base<T> & P in [[COPY]] : $*Base<T> & P to S in [[RESULT]] : $*S
366
+ let _ = baseTAndP_concrete as! S
367
+
368
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
369
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
370
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<T> & P to $BaseT
371
+ let _ = baseTAndP_concrete as? BaseT
372
+
373
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
374
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
375
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<T> & P to $BaseT
376
+ let _ = baseTAndP_concrete as! BaseT
377
+
378
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
379
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
380
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<T> & P to $BaseInt
381
+ let _ = baseTAndP_concrete as? BaseInt
382
+
383
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
384
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
385
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<T> & P to $BaseInt
386
+ let _ = baseTAndP_concrete as! BaseInt
387
+
388
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
389
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
390
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<T> & P to $BaseTAndP
391
+ let _ = baseTAndP_concrete as? BaseTAndP
392
+
393
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base<T> & P
394
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<T> & P
395
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<T> & P to $BaseTAndP
396
+ let _ = baseTAndP_concrete as! BaseTAndP
397
+
398
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %6 : $BaseIntAndP
399
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseIntAndP
400
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $BaseIntAndP to $Derived & R
401
+ let _ = baseIntAndP_archetype as? ( Derived & R )
402
+
403
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %6 : $BaseIntAndP
404
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseIntAndP
405
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $BaseIntAndP to $Derived & R
406
+ let _ = baseIntAndP_archetype as! ( Derived & R )
407
+
408
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
409
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
410
+ // CHECK-NEXT: [[COPY:%.*]] = alloc_stack $Base<Int> & P
411
+ // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base<Int> & P
412
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Optional<S>
413
+ // CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[RESULT]] : $*Optional<S>, #Optional.some
414
+ // CHECK-NEXT: checked_cast_addr_br take_always Base<Int> & P in [[COPY]] : $*Base<Int> & P to S in [[PAYLOAD]] : $*S
415
+ let _ = baseIntAndP_concrete as? S
416
+
417
+ // CHECK: [[COPY:%.*]] = alloc_stack $Base<Int> & P
418
+ // CHECK-NEXT: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
419
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
420
+ // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base<Int> & P
421
+ // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $S
422
+ // CHECK-NEXT: unconditional_checked_cast_addr take_always Base<Int> & P in [[COPY]] : $*Base<Int> & P to S in [[RESULT]] : $*S
423
+ let _ = baseIntAndP_concrete as! S
424
+
425
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
426
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
427
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<Int> & P to $DerivedT
428
+ let _ = baseIntAndP_concrete as? DerivedT
429
+
430
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
431
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
432
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<Int> & P to $DerivedT
433
+ let _ = baseIntAndP_concrete as! DerivedT
434
+
435
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
436
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
437
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<Int> & P to $BaseT
438
+ let _ = baseIntAndP_concrete as? BaseT
439
+
440
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
441
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
442
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<Int> & P to $BaseT
443
+ let _ = baseIntAndP_concrete as! BaseT
444
+
445
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
446
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
447
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<Int> & P to $BaseInt
448
+ let _ = baseIntAndP_concrete as? BaseInt
449
+
450
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
451
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
452
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<Int> & P to $BaseInt
453
+ let _ = baseIntAndP_concrete as! BaseInt
454
+
455
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
456
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
457
+ // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base<Int> & P to $BaseTAndP
458
+ let _ = baseIntAndP_concrete as? BaseTAndP
459
+
460
+ // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base<Int> & P
461
+ // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base<Int> & P
462
+ // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base<Int> & P to $BaseTAndP
463
+ let _ = baseIntAndP_concrete as! BaseTAndP
464
+
465
+ // CHECK: return
466
+ // CHECK-NEXT: }
169
467
}
0 commit comments