Skip to content

Commit e0391ca

Browse files
committed
SILGen: More subclass existential tests
1 parent 454495f commit e0391ca

File tree

2 files changed

+332
-6
lines changed

2 files changed

+332
-6
lines changed

test/SILGen/subclass_existentials.swift

Lines changed: 304 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,42 @@
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.
26

37
protocol Q {}
48

59
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+
}
817
}
918

1019
protocol P {
20+
init(protocolInit: ())
1121
func protocolSelfReturn() -> Self
1222
static func protocolSelfReturn() -> Self
1323
}
1424

1525
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+
}
1840
}
1941

2042
protocol R {}
@@ -128,7 +150,23 @@ func methodCalls(
128150
// CHECK: end_borrow [[BORROW]] from %0 : $Base<Int> & P
129151
let _: Base<Int> & P = baseAndP.protocolSelfReturn()
130152

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]]
131160
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]]
132170
let _: Base<Int> & P = baseAndPType.protocolSelfReturn()
133171

134172
// Partial applications
@@ -137,10 +175,15 @@ func methodCalls(
137175

138176
let _: () -> (Base<Int> & P) = baseAndPType.classSelfReturn
139177
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: }
140184
}
141185

142186
// 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-
144187
func functionConversions(
145188
returnsBaseAndP: @escaping () -> (Base<Int> & P),
146189
returnsBaseAndPType: @escaping () -> (Base<Int> & P).Type,
@@ -166,4 +209,259 @@ func functionConversions(
166209

167210
let _: () -> P = returnsDerivedAndR
168211
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: }
169467
}

0 commit comments

Comments
 (0)