// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -emit-silgen -parse-as-library -primary-file %s -verify | %FileCheck %s // RUN: %target-swift-frontend -emit-ir -parse-as-library -primary-file %s // Note: we pass -verify above to ensure there are no spurious // compiler warnings relating to casts. protocol Q {} class Base : Q { required init(classInit: ()) {} func classSelfReturn() -> Self { return self } static func classSelfReturn() -> Self { return self.init(classInit: ()) } } protocol P { init(protocolInit: ()) func protocolSelfReturn() -> Self static func protocolSelfReturn() -> Self } class Derived : Base, P { required init(protocolInit: ()) { super.init(classInit: ()) } required init(classInit: ()) { super.init(classInit: ()) } func protocolSelfReturn() -> Self { return self } static func protocolSelfReturn() -> Self { return self.init(classInit: ()) } } protocol R {} // CHECK-LABEL: sil hidden @_T021subclass_existentials11conversions8baseAndP7derived0fE1R0dE5PType0F4Type0fE5RTypeyAA1P_AA4BaseCySiGXc_AA7DerivedCAA1R_ANXcAaI_ALXcXpANmAaO_ANXcXptF : $@convention(thin) (@owned Base & P, @owned Derived, @owned Derived & R, @thick (Base & P).Type, @thick Derived.Type, @thick (Derived & R).Type) -> () { func conversions( baseAndP: Base & P, derived: Derived, derivedAndR: Derived & R, baseAndPType: (Base & P).Type, derivedType: Derived.Type, derivedAndRType: (Derived & R).Type) { // Values // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base & P // CHECK: [[PAYLOAD:%.*]] = open_existential_ref [[BORROWED]] : $Base & P // CHECK: [[REF:%.*]] = copy_value [[PAYLOAD]] // CHECK: [[BASE:%.*]] = upcast [[REF]] : $@opened("{{.*}}") Base & P to $Base // CHECK: destroy_value [[BASE]] : $Base // CHECK: end_borrow [[BORROWED]] from %0 : $Base & P let _: Base = baseAndP // CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base & P // CHECK: [[PAYLOAD:%.*]] = open_existential_ref [[BORROW]] : $Base & P // CHECK: [[RESULT:%.*]] = alloc_stack $P // CHECK: [[RESULT_PAYLOAD:%.*]] = init_existential_addr [[RESULT]] : $*P, $@opened("{{.*}}") Base & P // CHECK: [[REF:%.*]] = copy_value [[PAYLOAD]] // CHECK: store [[REF]] to [init] [[RESULT_PAYLOAD]] // CHECK: destroy_addr [[RESULT]] : $*P // CHECK: dealloc_stack [[RESULT]] : $*P // CHECK: end_borrow [[BORROW]] from %0 : $Base & P let _: P = baseAndP // CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base & P // CHECK: [[PAYLOAD:%.*]] = open_existential_ref [[BORROW]] : $Base & P // CHECK: [[RESULT:%.*]] = alloc_stack $Q // CHECK: [[RESULT_PAYLOAD:%.*]] = init_existential_addr [[RESULT]] : $*Q, $@opened("{{.*}}") Base & P // CHECK: [[REF:%.*]] = copy_value [[PAYLOAD]] // CHECK: store [[REF]] to [init] [[RESULT_PAYLOAD]] // CHECK: destroy_addr [[RESULT]] : $*Q // CHECK: dealloc_stack [[RESULT]] : $*Q // CHECK: end_borrow [[BORROW]] from %0 : $Base & P let _: Q = baseAndP // CHECK: [[BORROW:%.*]] = begin_borrow %2 : $Derived & R // CHECK: [[PAYLOAD:%.*]] = open_existential_ref [[BORROW]] : $Derived & R // CHECK: [[REF:%.*]] = copy_value [[PAYLOAD]] // CHECK: [[RESULT:%.*]] = init_existential_ref [[REF]] : $@opened("{{.*}}") Derived & R : $@opened("{{.*}}") Derived & R, $Base & P // CHECK: destroy_value [[RESULT]] // CHECK: end_borrow [[BORROW]] from %2 : $Derived & R let _: Base & P = derivedAndR // Metatypes // CHECK: [[PAYLOAD:%.*]] = open_existential_metatype %3 : $@thick (Base & P).Type to $@thick (@opened("{{.*}}") (Base & P)).Type // CHECK: [[RESULT:%.*]] = upcast [[PAYLOAD]] : $@thick (@opened("{{.*}}") (Base & P)).Type to $@thick Base.Type let _: Base.Type = baseAndPType // CHECK: [[PAYLOAD:%.*]] = open_existential_metatype %3 : $@thick (Base & P).Type to $@thick (@opened("{{.*}}") (Base & P)).Type // CHECK: [[RESULT:%.*]] = init_existential_metatype [[PAYLOAD]] : $@thick (@opened("{{.*}}") (Base & P)).Type, $@thick P.Type let _: P.Type = baseAndPType // CHECK: [[PAYLOAD:%.*]] = open_existential_metatype %3 : $@thick (Base & P).Type to $@thick (@opened("{{.*}}") (Base & P)).Type // CHECK: [[RESULT:%.*]] = init_existential_metatype [[PAYLOAD]] : $@thick (@opened("{{.*}}") (Base & P)).Type, $@thick Q.Type let _: Q.Type = baseAndPType // CHECK: [[RESULT:%.*]] = init_existential_metatype %4 : $@thick Derived.Type, $@thick (Base & P).Type let _: (Base & P).Type = derivedType // CHECK: [[PAYLOAD:%.*]] = open_existential_metatype %5 : $@thick (Derived & R).Type to $@thick (@opened("{{.*}}") (Derived & R)).Type // CHECK: [[RESULT:%.*]] = init_existential_metatype [[PAYLOAD]] : $@thick (@opened("{{.*}}") (Derived & R)).Type, $@thick (Base & P).Type let _: (Base & P).Type = derivedAndRType // CHECK: return } // CHECK-LABEL: sil hidden @_T021subclass_existentials11methodCalls8baseAndP0eF5PTypeyAA1P_AA4BaseCySiGXc_AaE_AHXcXptF : $@convention(thin) (@owned Base & P, @thick (Base & P).Type) -> () { func methodCalls( baseAndP: Base & P, baseAndPType: (Base & P).Type) { // CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base & P // CHECK: [[PAYLOAD:%.*]] = open_existential_ref [[BORROW]] : $Base & P to $@opened("{{.*}}") Base & P // CHECK: [[REF:%.*]] = copy_value [[PAYLOAD]] : $@opened("{{.*}}") Base & P // CHECK: [[CLASS_REF:%.*]] = upcast [[REF]] : $@opened("{{.*}}") Base & P to $Base // CHECK: [[METHOD:%.*]] = class_method [[CLASS_REF]] : $Base, #Base.classSelfReturn!1 : (Base) -> () -> @dynamic_self Base, $@convention(method) <τ_0_0> (@guaranteed Base<τ_0_0>) -> @owned Base<τ_0_0> // CHECK: [[RESULT_CLASS_REF:%.*]] = apply [[METHOD]]([[CLASS_REF]]) : $@convention(method) <τ_0_0> (@guaranteed Base<τ_0_0>) -> @owned Base<τ_0_0> // CHECK: destroy_value [[CLASS_REF]] : $Base // CHECK: [[RESULT_REF:%.*]] = unchecked_ref_cast [[RESULT_CLASS_REF]] : $Base to $@opened("{{.*}}") Base & P // CHECK: [[RESULT:%.*]] = init_existential_ref [[RESULT_REF]] : $@opened("{{.*}}") Base & P : $@opened("{{.*}}") Base & P, $Base & P // CHECK: destroy_value [[RESULT]] : $Base & P // CHECK: end_borrow [[BORROW]] from %0 : $Base & P let _: Base & P = baseAndP.classSelfReturn() // CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base & P // CHECK: [[PAYLOAD:%.*]] = open_existential_ref [[BORROW]] : $Base & P to $@opened("{{.*}}") Base & P // CHECK: [[RESULT_BOX:%.*]] = alloc_stack $@opened("{{.*}}") Base & P // CHECK: [[SELF_BOX:%.*]] = alloc_stack $@opened("{{.*}}") Base & P // CHECK: store_borrow [[PAYLOAD]] to [[SELF_BOX]] : $*@opened("{{.*}}") Base & P // CHECK: [[METHOD:%.*]] = witness_method $@opened("{{.*}}") Base & P, #P.protocolSelfReturn!1 : (Self) -> () -> @dynamic_self Self, [[PAYLOAD]] : $@opened("{{.*}}") Base & P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0 // CHECK: apply [[METHOD]]<@opened("{{.*}}") Base & P>([[RESULT_BOX]], [[SELF_BOX]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0 // CHECK: dealloc_stack [[SELF_BOX]] : $*@opened("{{.*}}") Base & P // CHECK: [[RESULT_REF:%.*]] = load [take] [[RESULT_BOX]] : $*@opened("{{.*}}") Base & P // CHECK: [[RESULT:%.*]] = init_existential_ref [[RESULT_REF]] : $@opened("{{.*}}") Base & P : $@opened("{{.*}}") Base & P, $Base & P // CHECK: destroy_value [[RESULT]] : $Base & P // CHECK: dealloc_stack [[RESULT_BOX]] : $*@opened("{{.*}}") Base & P // CHECK: end_borrow [[BORROW]] from %0 : $Base & P let _: Base & P = baseAndP.protocolSelfReturn() // CHECK: [[METATYPE:%.*]] = open_existential_metatype %1 : $@thick (Base & P).Type to $@thick (@opened("{{.*}}") (Base & P)).Type // CHECK: [[METATYPE_REF:%.*]] = upcast [[METATYPE]] : $@thick (@opened("{{.*}}") (Base & P)).Type to $@thick Base.Type // CHECK: [[METHOD:%.*]] = function_ref @_T021subclass_existentials4BaseC15classSelfReturnACyxGXDyFZ : $@convention(method) <τ_0_0> (@thick Base<τ_0_0>.Type) -> @owned Base<τ_0_0> // CHECK: [[RESULT_REF2:%.*]] = apply [[METHOD]]([[METATYPE_REF]]) // CHECK: [[RESULT_REF:%.*]] = unchecked_ref_cast [[RESULT_REF2]] : $Base to $@opened("{{.*}}") (Base & P) // CHECK: [[RESULT:%.*]] = init_existential_ref [[RESULT_REF]] : $@opened("{{.*}}") (Base & P) : $@opened("{{.*}}") (Base & P), $Base & P // CHECK: destroy_value [[RESULT]] let _: Base & P = baseAndPType.classSelfReturn() // CHECK: [[METATYPE:%.*]] = open_existential_metatype %1 : $@thick (Base & P).Type to $@thick (@opened("{{.*}}") (Base & P)).Type // CHECK: [[RESULT:%.*]] = alloc_stack $@opened("{{.*}}") (Base & P) // CHECK: [[METHOD:%.*]] = witness_method $@opened("{{.*}}") (Base & P), #P.protocolSelfReturn!1 : (Self.Type) -> () -> @dynamic_self Self, [[METATYPE]] : $@thick (@opened("{{.*}}") (Base & P)).Type : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> @out τ_0_0 // CHECK: apply [[METHOD]]<@opened("{{.*}}") (Base & P)>([[RESULT]], [[METATYPE]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> @out τ_0_0 // CHECK: [[RESULT_REF:%.*]] = load [take] [[RESULT]] : $*@opened("{{.*}}") (Base & P) // CHECK: [[RESULT_VALUE:%.*]] = init_existential_ref [[RESULT_REF]] : $@opened("{{.*}}") (Base & P) : $@opened("{{.*}}") (Base & P), $Base & P // CHECK: destroy_value [[RESULT_VALUE]] // CHECK: dealloc_stack [[RESULT]] let _: Base & P = baseAndPType.protocolSelfReturn() // Partial applications let _: () -> (Base & P) = baseAndP.classSelfReturn let _: () -> (Base & P) = baseAndP.protocolSelfReturn let _: () -> (Base & P) = baseAndPType.classSelfReturn let _: () -> (Base & P) = baseAndPType.protocolSelfReturn let _: () -> (Base & P) = baseAndPType.init(classInit:) let _: () -> (Base & P) = baseAndPType.init(protocolInit:) // CHECK: return // CHECK-NEXT: } } protocol PropertyP { var p: PropertyP & PropertyC { get set } subscript(key: Int) -> Int { get set } } class PropertyC { var c: PropertyP & PropertyC { get { return self as! PropertyP & PropertyC } set { } } subscript(key: (Int, Int)) -> Int { get { return 0 } set { } } } // CHECK-LABEL: sil hidden @_T021subclass_existentials16propertyAccessesyyAA9PropertyP_AA0E1CCXcF : $@convention(thin) (@owned PropertyC & PropertyP) -> () { func propertyAccesses(_ x: PropertyP & PropertyC) { var xx = x xx.p.p = x xx.c.c = x propertyAccesses(xx.p) propertyAccesses(xx.c) _ = xx[1] xx[1] = 1 xx[1] += 1 _ = xx[(1, 2)] xx[(1, 2)] = 1 xx[(1, 2)] += 1 } // CHECK-LABEL: sil hidden @_T021subclass_existentials19functionConversions15returnsBaseAndP0efG5PType0E7Derived0eI4Type0eiG1R0eiG5RTypeyAA1P_AA0F0CySiGXcyc_AaI_ALXcXpycAA0I0CycANmycAA1R_ANXcycAaO_ANXcXpyctF : $@convention(thin) (@owned @callee_guaranteed () -> @owned Base & P, @owned @callee_guaranteed () -> @thick (Base & P).Type, @owned @callee_guaranteed () -> @owned Derived, @owned @callee_guaranteed () -> @thick Derived.Type, @owned @callee_guaranteed () -> @owned Derived & R, @owned @callee_guaranteed () -> @thick (Derived & R).Type) -> () { func functionConversions( returnsBaseAndP: @escaping () -> (Base & P), returnsBaseAndPType: @escaping () -> (Base & P).Type, returnsDerived: @escaping () -> Derived, returnsDerivedType: @escaping () -> Derived.Type, returnsDerivedAndR: @escaping () -> Derived & R, returnsDerivedAndRType: @escaping () -> (Derived & R).Type) { let _: () -> Base = returnsBaseAndP let _: () -> Base.Type = returnsBaseAndPType let _: () -> P = returnsBaseAndP let _: () -> P.Type = returnsBaseAndPType let _: () -> (Base & P) = returnsDerived let _: () -> (Base & P).Type = returnsDerivedType let _: () -> Base = returnsDerivedAndR let _: () -> Base.Type = returnsDerivedAndRType let _: () -> (Base & P) = returnsDerivedAndR let _: () -> (Base & P).Type = returnsDerivedAndRType let _: () -> P = returnsDerivedAndR let _: () -> P.Type = returnsDerivedAndRType // CHECK: return % // CHECK-NEXT: } } // CHECK-LABEL: sil hidden @_T021subclass_existentials9downcasts8baseAndP7derived0dE5PType0F4TypeyAA1P_AA4BaseCySiGXc_AA7DerivedCAaG_AJXcXpALmtF : $@convention(thin) (@owned Base & P, @owned Derived, @thick (Base & P).Type, @thick Derived.Type) -> () { func downcasts( baseAndP: Base & P, derived: Derived, baseAndPType: (Base & P).Type, derivedType: Derived.Type) { // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $Derived let _ = baseAndP as? Derived // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $Derived let _ = baseAndP as! Derived // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $Derived & R let _ = baseAndP as? (Derived & R) // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $Derived & R let _ = baseAndP as! (Derived & R) // CHECK: checked_cast_br %3 : $@thick Derived.Type to $@thick (Derived & R).Type let _ = derivedType as? (Derived & R).Type // CHECK: unconditional_checked_cast %3 : $@thick Derived.Type to $@thick (Derived & R).Type let _ = derivedType as! (Derived & R).Type // CHECK: checked_cast_br %2 : $@thick (Base & P).Type to $@thick Derived.Type let _ = baseAndPType as? Derived.Type // CHECK: unconditional_checked_cast %2 : $@thick (Base & P).Type to $@thick Derived.Type let _ = baseAndPType as! Derived.Type // CHECK: checked_cast_br %2 : $@thick (Base & P).Type to $@thick (Derived & R).Type let _ = baseAndPType as? (Derived & R).Type // CHECK: unconditional_checked_cast %2 : $@thick (Base & P).Type to $@thick (Derived & R).Type let _ = baseAndPType as! (Derived & R).Type // CHECK: return // CHECK-NEXT: } } // CHECK-LABEL: sil hidden @_T021subclass_existentials16archetypeUpcasts9baseTAndP0E7IntAndP7derivedyq__q0_q1_tAA4BaseCyxGRb_AA1PR_AGySiGRb0_AaIR0_AA7DerivedCRb1_r2_lF : $@convention(thin) , BaseTAndP : P, BaseIntAndP : Base, BaseIntAndP : P, DerivedT : Derived> (@owned BaseTAndP, @owned BaseIntAndP, @owned DerivedT) -> () { func archetypeUpcasts & P, BaseIntAndP : Base & P, DerivedT : Derived>( baseTAndP: BaseTAndP, baseIntAndP : BaseIntAndP, derived : DerivedT) { // CHECK: [[BORROWED:%.*]] = begin_borrow %0 : $BaseTAndP // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseTAndP // CHECK-NEXT: init_existential_ref [[COPIED]] : $BaseTAndP : $BaseTAndP, $Base & P let _: Base & P = baseTAndP // CHECK: [[BORROWED:%.*]] = begin_borrow %1 : $BaseIntAndP // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseIntAndP // CHECK-NEXT: init_existential_ref [[COPIED]] : $BaseIntAndP : $BaseIntAndP, $Base & P let _: Base & P = baseIntAndP // CHECK: [[BORROWED:%.*]] = begin_borrow %2 : $DerivedT // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $DerivedT // CHECK-NEXT: init_existential_ref [[COPIED]] : $DerivedT : $DerivedT, $Base & P let _: Base & P = derived // CHECK: return // CHECK-NEXT: } } // CHECK-LABEL: sil hidden @_T021subclass_existentials18archetypeDowncasts1s1t2pt5baseT0F3Int0f6TAndP_C00fg5AndP_C008derived_C00ji2R_C00fH10P_concrete0fgi2P_K0yx_q_q0_q1_q2_q3_q4_q5_AA1R_AA7DerivedCXcAA1P_AA4BaseCyq_GXcAaQ_ASySiGXctAaQR0_ATRb1_AURb2_ATRb3_AaQR3_AURb4_AaQR4_APRb5_r6_lF : $@convention(thin) , BaseInt : Base, BaseTAndP : Base, BaseTAndP : P, BaseIntAndP : Base, 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 & P, @owned Base & P) -> () { func archetypeDowncasts, BaseInt : Base, BaseTAndP : Base & P, BaseIntAndP : Base & P, DerivedT : Derived>( s: S, t: T, pt: PT, baseT : BaseT, baseInt : BaseInt, baseTAndP_archetype: BaseTAndP, baseIntAndP_archetype : BaseIntAndP, derived_archetype : DerivedT, derivedAndR_archetype : Derived & R, baseTAndP_concrete: Base & P, baseIntAndP_concrete: Base & P) { // CHECK: [[COPY:%.*]] = alloc_stack $S // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base & P // CHECK-NEXT: checked_cast_addr_br take_always S in [[COPY]] : $*S to Base & P in [[RESULT]] : $*Base & P let _ = s as? (Base & P) // CHECK: [[COPY:%.*]] = alloc_stack $S // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base & P // CHECK-NEXT: unconditional_checked_cast_addr S in [[COPY]] : $*S to Base & P in [[RESULT]] : $*Base & P let _ = s as! (Base & P) // CHECK: [[COPY:%.*]] = alloc_stack $S // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base & P // CHECK-NEXT: checked_cast_addr_br take_always S in [[COPY]] : $*S to Base & P in [[RESULT]] : $*Base & P let _ = s as? (Base & P) // CHECK: [[COPY:%.*]] = alloc_stack $S // CHECK-NEXT: copy_addr %0 to [initialization] [[COPY]] : $*S // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Base & P // CHECK-NEXT: unconditional_checked_cast_addr S in [[COPY]] : $*S to Base & P in [[RESULT]] : $*Base & P let _ = s as! (Base & P) // CHECK: [[BORROWED:%.*]] = begin_borrow %5 : $BaseTAndP // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseTAndP // CHECK-NEXT: checked_cast_br [[COPIED]] : $BaseTAndP to $Derived & R let _ = baseTAndP_archetype as? (Derived & R) // CHECK: [[BORROWED:%.*]] = begin_borrow %5 : $BaseTAndP // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseTAndP // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $BaseTAndP to $Derived & R let _ = baseTAndP_archetype as! (Derived & R) // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: [[COPY:%.*]] = alloc_stack $Base & P // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base & P // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Optional // CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[RESULT]] : $*Optional, #Optional.some // CHECK-NEXT: checked_cast_addr_br take_always Base & P in [[COPY]] : $*Base & P to S in [[PAYLOAD]] : $*S let _ = baseTAndP_concrete as? S // CHECK: [[COPY:%.*]] = alloc_stack $Base & P // CHECK-NEXT: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base & P // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $S // CHECK-NEXT: unconditional_checked_cast_addr Base & P in [[COPY]] : $*Base & P to S in [[RESULT]] : $*S let _ = baseTAndP_concrete as! S // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $BaseT let _ = baseTAndP_concrete as? BaseT // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $BaseT let _ = baseTAndP_concrete as! BaseT // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $BaseInt let _ = baseTAndP_concrete as? BaseInt // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $BaseInt let _ = baseTAndP_concrete as! BaseInt // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $BaseTAndP let _ = baseTAndP_concrete as? BaseTAndP // CHECK: [[BORROWED:%.*]] = begin_borrow %9 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $BaseTAndP let _ = baseTAndP_concrete as! BaseTAndP // CHECK: [[BORROWED:%.*]] = begin_borrow %6 : $BaseIntAndP // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseIntAndP // CHECK-NEXT: checked_cast_br [[COPIED]] : $BaseIntAndP to $Derived & R let _ = baseIntAndP_archetype as? (Derived & R) // CHECK: [[BORROWED:%.*]] = begin_borrow %6 : $BaseIntAndP // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $BaseIntAndP // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $BaseIntAndP to $Derived & R let _ = baseIntAndP_archetype as! (Derived & R) // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: [[COPY:%.*]] = alloc_stack $Base & P // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base & P // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Optional // CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[RESULT]] : $*Optional, #Optional.some // CHECK-NEXT: checked_cast_addr_br take_always Base & P in [[COPY]] : $*Base & P to S in [[PAYLOAD]] : $*S let _ = baseIntAndP_concrete as? S // CHECK: [[COPY:%.*]] = alloc_stack $Base & P // CHECK-NEXT: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: store [[COPIED]] to [init] [[COPY]] : $*Base & P // CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $S // CHECK-NEXT: unconditional_checked_cast_addr Base & P in [[COPY]] : $*Base & P to S in [[RESULT]] : $*S let _ = baseIntAndP_concrete as! S // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $DerivedT let _ = baseIntAndP_concrete as? DerivedT // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $DerivedT let _ = baseIntAndP_concrete as! DerivedT // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $BaseT let _ = baseIntAndP_concrete as? BaseT // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $BaseT let _ = baseIntAndP_concrete as! BaseT // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $BaseInt let _ = baseIntAndP_concrete as? BaseInt // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $BaseInt let _ = baseIntAndP_concrete as! BaseInt // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: checked_cast_br [[COPIED]] : $Base & P to $BaseTAndP let _ = baseIntAndP_concrete as? BaseTAndP // CHECK: [[BORROWED:%.*]] = begin_borrow %10 : $Base & P // CHECK-NEXT: [[COPIED:%.*]] = copy_value [[BORROWED]] : $Base & P // CHECK-NEXT: unconditional_checked_cast [[COPIED]] : $Base & P to $BaseTAndP let _ = baseIntAndP_concrete as! BaseTAndP // CHECK: return // CHECK-NEXT: } }