// RUN: %target-swift-emit-silgen -enable-sil-opaque-values -Xllvm -sil-full-demangle -parse-stdlib -parse-as-library -module-name Swift %s | %FileCheck %s --check-prefix=CHECK // Test SILGen -enable-sil-opaque-values typealias AnyObject = Builtin.AnyObject public enum Optional { case none case some(T) } public protocol ExpressibleByNilLiteral { init(nilLiteral: ()) } extension Optional : ExpressibleByNilLiteral { public init(nilLiteral: ()) { self = .none } } func _diagnoseUnexpectedNilOptional(_filenameStart: Builtin.RawPointer, _filenameLength: Builtin.Word, _filenameIsASCII: Builtin.Int1, _line: Builtin.Word, _isImplicitUnwrap: Builtin.Int1) { // This would usually contain an assert, but we don't need one since we are // just emitting SILGen. } precedencegroup AssignmentPrecedence { assignment: true } precedencegroup CastingPrecedence {} precedencegroup ComparisonPrecedence {} precedencegroup TernaryPrecedence {} public protocol Error {} public protocol _ObjectiveCBridgeable {} protocol EmptyP {} struct AddressOnlyStruct : EmptyP {} struct String { var ptr: Builtin.NativeObject } public typealias _MaxBuiltinIntegerType = Builtin.IntLiteral public protocol _ExpressibleByBuiltinIntegerLiteral { init(_builtinIntegerLiteral value: _MaxBuiltinIntegerType) } public protocol ExpressibleByIntegerLiteral { associatedtype IntegerLiteralType : _ExpressibleByBuiltinIntegerLiteral init(integerLiteral value: IntegerLiteralType) } extension ExpressibleByIntegerLiteral where Self : _ExpressibleByBuiltinIntegerLiteral { @_transparent public init(integerLiteral value: Self) { self = value } } public protocol ExpressibleByFloatLiteral {} typealias Bool = Builtin.Int1 public struct Int64 : ExpressibleByIntegerLiteral, _ExpressibleByBuiltinIntegerLiteral { public var _value: Builtin.Int64 public init(_builtinIntegerLiteral x: _MaxBuiltinIntegerType) { _value = Builtin.s_to_s_checked_trunc_IntLiteral_Int64(x).0 } public typealias IntegerLiteralType = Int64 public init(integerLiteral value: Int64) { self = value } } public protocol UnkeyedDecodingContainer { var isAtEnd: Builtin.Int1 { get } } public protocol Decoder { func unkeyedContainer() throws -> UnkeyedDecodingContainer } protocol FooP { func foo() } struct AnyStruct { let a: Any } protocol P { var x : Builtin.Int64 { get } } protocol P2 : P {} struct TrivialStruct { var x: Builtin.Int64 } extension TrivialStruct : P2 {} protocol Clonable { func maybeClone() -> Self? } func unreachableF() -> (Builtin.Int64, T)? { /* no body */ } protocol ConvertibleToP { func asP() -> P } indirect enum IndirectEnum { case Nil case Node(T) } protocol SubscriptableGet { subscript(a : Builtin.Int64) -> Builtin.Int64 { get } } protocol SubscriptableGetSet { subscript(a : Builtin.Int64) -> Builtin.Int64 { get set } } var subscriptableGet : SubscriptableGet? var subscriptableGetSet : SubscriptableGetSet? func genericInout(_: inout T) {} // ============================================================================= // Begin Test Cases // ============================================================================= enum PAndSEnum { case A(EmptyP, String) } // Tests Empty protocol + Builtin.NativeObject enum (including opaque tuples as a return value) // --- // Swift.f010_PAndS_cases() -> () // CHECK-LABEL: sil hidden [ossa] @$ss16f010_PAndS_casesyyF : $@convention(thin) () -> () { // HECK: bb0: // HECK: [[MTYPE:%.*]] = metatype $@thin PAndSEnum.Type // HECK: [[EAPPLY:%.*]] = apply {{.*}}([[MTYPE]]) : $@convention(thin) (@thin PAndSEnum.Type) -> @owned @callee_guaranteed (@in_guaranteed EmptyP, @guaranteed String) -> @out PAndSEnum // HECK: destroy_value [[EAPPLY]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss16f010_PAndS_casesyyF' func f010_PAndS_cases() { _ = PAndSEnum.A } // Init of Empty protocol + Builtin.NativeObject enum (including opaque tuples as a return value) // --- // implicit closure #2 (Swift.EmptyP, Swift.String) -> Swift.PAndSEnum in implicit closure #1 (Swift.PAndSEnum.Type) -> (Swift.EmptyP, Swift.String) -> Swift.PAndSEnum in Swift.f010_PAndS_cases() -> () // CHECK-LABEL: sil private [ossa] @$ss16f010_PAndS_casesyyFs0B5SEnumOs6EmptyP_p_SStcACmcfu_ACsAD_p_SStcfu0_ : $@convention(thin) (@in_guaranteed any EmptyP, @guaranteed String, @thin PAndSEnum.Type) -> @out PAndSEnum { // HECK: bb0([[ARG0:%.*]] : @guaranteed $any EmptyP, [[ARG1:%.*]] : @guaranteed $String, [[ARG2:%.*]] : $@thin PAndSEnum.Type): // HECK: [[COPY0:%.*]] = copy_value [[ARG0]] // HECK: [[COPY1:%.*]] = copy_value [[ARG1]] // HECK: [[RTUPLE:%.*]] = tuple ([[COPY0]] : $any EmptyP, [[COPY1]] : $String) // HECK: [[RETVAL:%.*]] = enum $PAndSEnum, #PAndSEnum.A!enumelt, [[RTUPLE]] : $(any EmptyP, String) // HECK: return [[RETVAL]] : $PAndSEnum // CHECK-LABEL: } // end sil function '$ss16f010_PAndS_casesyyFs0B5SEnumOs6EmptyP_p_SStcACmcfu_ACsAD_p_SStcfu0_' // Test emitBuiltinReinterpretCast. // --- // CHECK-LABEL: sil hidden [ossa] @$ss12f020_bitCast_2toq_x_q_mtr0_lF : $@convention(thin) (@in_guaranteed T, @thick U.Type) -> @out U { // HECK: bb0([[ARG:%.*]] : @guaranteed $T, // HECK: [[COPY:%.*]] = copy_value [[ARG]] : $T // HECK: [[CAST:%.*]] = unchecked_bitwise_cast [[COPY]] : $T to $U // HECK: [[RET:%.*]] = copy_value [[CAST]] : $U // HECK: destroy_value [[COPY]] : $T // HECK: return [[RET]] : $U // CHECK-LABEL: } // end sil function '$ss12f020_bitCast_2toq_x_q_mtr0_lF' func f020_bitCast(_ x: T, to type: U.Type) -> U { return Builtin.reinterpretCast(x) } // Test emitBuiltinCastReference // --- // CHECK-LABEL: sil hidden [ossa] @$ss12f021_refCast_2toq_x_q_mtr0_lF : $@convention(thin) (@in_guaranteed T, @thick U.Type) -> @out U { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T, %1 : $@thick U.Type): // HECK: [[COPY:%.*]] = copy_value [[ARG]] : $T // HECK: [[SRC:%.*]] = alloc_stack $T // HECK: store [[COPY]] to [init] [[SRC]] : $*T // HECK: [[DEST:%.*]] = alloc_stack $U // HECK: unchecked_ref_cast_addr T in [[SRC]] : $*T to U in [[DEST]] : $*U // HECK: [[LOAD:%.*]] = load [take] [[DEST]] : $*U // HECK: dealloc_stack [[DEST]] : $*U // HECK: dealloc_stack [[SRC]] : $*T // CHECK-NOT: destroy_value [[ARG]] : $T // HECK: return [[LOAD]] : $U // CHECK-LABEL: } // end sil function '$ss12f021_refCast_2toq_x_q_mtr0_lF' func f021_refCast(_ x: T, to: U.Type) -> U { return Builtin.castReference(x) } // Test unsafe_bitwise_cast nontrivial ownership. // --- // CHECK-LABEL: sil [ossa] @$ss18f022_unsafeBitCast_2toq_x_q_mtr0_lF : $@convention(thin) (@in_guaranteed T, @thick U.Type) -> @out U { // HECK: bb0([[ARG0:%.*]] : @guaranteed $T, [[ARG1:%.*]] : $@thick U.Type): // HECK: [[ARG_COPY:%.*]] = copy_value [[ARG0]] : $T // HECK: [[RESULT:%.*]] = unchecked_bitwise_cast [[ARG_COPY]] : $T to $U // HECK: [[RESULT_COPY:%.*]] = copy_value [[RESULT]] : $U // HECK: destroy_value [[ARG_COPY]] : $T // HECK: return [[RESULT_COPY]] : $U // CHECK-LABEL: } // end sil function '$ss18f022_unsafeBitCast_2toq_x_q_mtr0_lF' public func f022_unsafeBitCast(_ x: T, to type: U.Type) -> U { return Builtin.reinterpretCast(x) } // Test emitSemanticStore. // --- // CHECK-LABEL: sil hidden [ossa] @$ss16f030_assigninoutyyxz_xtlF : $@convention(thin) (@inout T, @in_guaranteed T) -> () { // CHECK: bb0([[ARG0:%.*]] : $*T, [[ARG1:%.*]] : @guaranteed $T): // HECK: [[CPY:%.*]] = copy_value [[ARG1]] : $T // HECK: [[READ:%.*]] = begin_access [modify] [unknown] [[ARG0]] : $*T // HECK: assign [[CPY]] to [[READ]] : $*T // CHECK-NOT: destroy_value [[ARG1]] : $T // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss16f030_assigninoutyyxz_xtlF' func f030_assigninout(_ a: inout T, _ b: T) { a = b } // Test that we no longer use copy_addr or tuple_element_addr when copy by value is possible // --- // CHECK-LABEL: sil hidden [ossa] @$ss19f040_tupleReturnIntyBi64_Bi64__xt_tlF : $@convention(thin) (Builtin.Int64, @in_guaranteed T) -> Builtin.Int64 { // HECK: bb0([[ARG0:%.*]] : $Builtin.Int64, [[ARG1:%.*]] : $T): // HECK: [[ARG1_COPY:%.*]] = copy_value [[ARG1]] // HECK: [[TPL:%.*]] = tuple ([[ARG0]] : $Builtin.Int64, [[ARG1_COPY]] : $T) // HECK: [[BORROWED_ARG1:%.*]] = begin_borrow [[TPL]] : $(Builtin.Int64, T) // HECK: [[CPY:%.*]] = copy_value [[BORROWED_ARG1]] : $(Builtin.Int64, T) // HECK: [[BORROWED_CPY:%.*]] = begin_borrow [[CPY]] // HECK: [[INT:%.*]] = tuple_extract [[BORROWED_CPY]] : $(Builtin.Int64, T), 0 // HECK: [[GEN:%.*]] = tuple_extract [[BORROWED_CPY]] : $(Builtin.Int64, T), 1 // HECK: [[COPY_GEN:%.*]] = copy_value [[GEN]] // HECK: destroy_value [[COPY_GEN]] // HECK: end_borrow [[BORROWED_CPY]] // HECK: destroy_value [[CPY]] // HECK: end_borrow [[BORROWED_ARG1]] : $(Builtin.Int64, T) // HECK: destroy_value [[TPL]] : $(Builtin.Int64, T) // HECK: return [[INT]] // CHECK-LABEL: } // end sil function '$ss19f040_tupleReturnIntyBi64_Bi64__xt_tlF' func f040_tupleReturnInt(_ x: (Builtin.Int64, T)) -> Builtin.Int64 { let y = x.0 return y } // Test returning an opaque tuple of tuples. // --- // CHECK-LABEL: sil hidden [noinline] [ossa] @$ss16f050_multiResultyx_x_xttxlF : $@convention(thin) (@in_guaranteed T) -> (@out T, @out T, @out T) { // HECK: bb0(%0 : $T): // HECK: %[[CP1:.*]] = copy_value %{{.*}} : $T // HECK: %[[CP2:.*]] = copy_value %{{.*}} : $T // HECK: %[[CP3:.*]] = copy_value %{{.*}} : $T // CHECK-NOT: destroy_value %0 : $T // HECK: %[[TPL:.*]] = tuple (%[[CP1]] : $T, %[[CP2]] : $T, %[[CP3]] : $T) // HECK: return %[[TPL]] : $(T, T, T) // CHECK-LABEL: } // end sil function '$ss16f050_multiResultyx_x_xttxlF' @inline(never) func f050_multiResult(_ t: T) -> (T, (T, T)) { return (t, (t, t)) } // Test returning an opaque tuple of tuples as a concrete tuple. // --- // CHECK-LABEL: sil [ossa] @$ss20f060_callMultiResult1iBi64__Bi64__Bi64_ttBi64__tF : $@convention(thin) (Builtin.Int64) -> (Builtin.Int64, Builtin.Int64, Builtin.Int64) { // HECK: bb0(%0 : $Builtin.Int64): // HECK: %[[FN:.*]] = function_ref @$s20opaque_values_silgen21f050_multiResultyx_x_xttxlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> (@out τ_0_0, @out τ_0_0, @out τ_0_0) // HECK: %[[TPL:.*]] = apply %[[FN]](%0) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> (@out τ_0_0, @out τ_0_0, @out τ_0_0) // HECK: %[[I1:.*]] = tuple_extract %[[TPL]] : $(Builtin.Int64, Builtin.Int64, Builtin.Int64), 0 // HECK: %[[I2:.*]] = tuple_extract %[[TPL]] : $(Builtin.Int64, Builtin.Int64, Builtin.Int64), 1 // HECK: %[[I3:.*]] = tuple_extract %[[TPL]] : $(Builtin.Int64, Builtin.Int64, Builtin.Int64), 2 // HECK: %[[R:.*]] = tuple (%[[I1]] : $Builtin.Int64, %[[I2]] : $Builtin.Int64, %[[I3]] : $Builtin.Int64) // HECK: return %[[R]] : $(Builtin.Int64, Builtin.Int64, Builtin.Int64) // CHECK-LABEL: } // end sil function '$ss20f060_callMultiResult1iBi64__Bi64__Bi64_ttBi64__tF' public func f060_callMultiResult(i: Builtin.Int64) -> (Builtin.Int64, (Builtin.Int64, Builtin.Int64)) { return f050_multiResult(i) } // SILGen, prepareArchetypeCallee. Materialize a // non-class-constrained self from a class-constrained archetype. // --- // CHECK-LABEL: sil hidden [ossa] @$ss20f070_materializeSelf1tyx_tRlzCs4FooPRzlF : $@convention(thin) (@guaranteed T) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // HECK: [[WITNESS_METHOD:%.*]] = witness_method $T, #FooP.foo : (Self) -> () -> () : $@convention(witness_method: FooP) <τ_0_0 where τ_0_0 : FooP> (@in_guaranteed τ_0_0) -> () // HECK: apply [[WITNESS_METHOD]]([[ARG]]) : $@convention(witness_method: FooP) <τ_0_0 where τ_0_0 : FooP> (@in_guaranteed τ_0_0) -> () // CHECK-NOT: destroy_value [[ARG]] : $T // HECK: return %{{[0-9]+}} : $() // CHECK-LABEL: } // end sil function '$ss20f070_materializeSelf1tyx_tRlzCs4FooPRzlF' func f070_materializeSelf(t: T) where T: AnyObject { t.foo() } // Test open existential with opaque values // --- // CHECK-LABEL: sil hidden [ossa] @$ss8f080_bar1pBi64_s1P_p_tF : $@convention(thin) (@in_guaranteed any P) -> Builtin.Int64 { // CHECK: bb0([[ARG:%.*]] : @guaranteed $any P): // HECK: [[OPENED_ARG:%.*]] = open_existential_value [[ARG]] : $any P to $@opened // HECK: [[WITNESS_FUNC:%.*]] = witness_method $@opened // HECK: [[RESULT:%.*]] = apply [[WITNESS_FUNC]]<{{.*}}>([[OPENED_ARG]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int64 // CHECK-NOT: destroy_value [[ARG]] : $any P // HECK: return [[RESULT]] : $Builtin.Int64 // CHECK-LABEL: } // end sil function '$ss8f080_bar1pBi64_s1P_p_tF' func f080_bar(p: P) -> Builtin.Int64 { return p.x } // Test OpaqueTypeLowering copyValue and destroyValue. // --- // CHECK-LABEL: sil hidden [ossa] @$ss11f090_calleryxxlF : $@convention(thin) (@in_guaranteed T) -> @out T { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // CHECK-NOT: copy_value // HECK: [[RESULT:%.*]] = apply {{%.*}}([[ARG]]) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0 // CHECK-NOT: destroy_value [[ARG]] : $T // HECK: return %{{.*}} : $T // CHECK-LABEL: } // end sil function '$ss11f090_calleryxxlF' func f090_caller(_ t: T) -> T { return f090_caller(t) } // Test a simple opaque parameter and return value. // --- // CHECK-LABEL: sil hidden [ossa] @$ss13f100_identityyxxlF : $@convention(thin) (@in_guaranteed T) -> @out T { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] : $T // CHECK-NOT: destroy_value [[ARG]] : $T // HECK: return [[COPY_ARG]] : $T // CHECK-LABEL: } // end sil function '$ss13f100_identityyxxlF' func f100_identity(_ t: T) -> T { return t } // Test a guaranteed opaque parameter. // --- // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$ss19f110_GuaranteedSelfVs4FooPssACP3fooyyFTW : $@convention(witness_method: FooP) (@in_guaranteed f110_GuaranteedSelf) -> () { // CHECK: bb0(%0 : $f110_GuaranteedSelf): // HECK: %[[F:.*]] = function_ref @$s20opaque_values_silgen21f110_GuaranteedSelfV3fooyyF : $@convention(method) (f110_GuaranteedSelf) -> () // HECK: apply %[[F]](%0) : $@convention(method) (f110_GuaranteedSelf) -> () // HECK: return // CHECK-LABEL: } // end sil function '$ss19f110_GuaranteedSelfVs4FooPssACP3fooyyFTW' struct f110_GuaranteedSelf : FooP { func foo() {} } // Tests a corner case wherein we used to do a temporary and return a pointer to T instead of T // --- // CHECK-LABEL: sil hidden [ossa] @$ss16f120_returnValueyxxlF : $@convention(thin) (@in_guaranteed T) -> @out T { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // HECK: [[COPY_ARG1:%.*]] = copy_value [[ARG]] : $T // HECK: [[BORROWED_ARG2:%.*]] = begin_borrow [[COPY_ARG1]] // HECK: [[COPY_ARG2:%.*]] = copy_value [[BORROWED_ARG2]] : $T // HECK: end_borrow [[BORROWED_ARG2]] // HECK: return [[COPY_ARG2]] : $T // CHECK-LABEL: } // end sil function '$ss16f120_returnValueyxxlF' func f120_returnValue(_ x: T) -> T { let y = x return y } // Tests Optional initialization by value // --- // CHECK-LABEL: sil hidden [ossa] @$ss9f130_wrapyxSgxlF : $@convention(thin) (@in_guaranteed T) -> @out Optional { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] : $T // HECK: [[OPTIONAL_ARG:%.*]] = enum $Optional, #Optional.some!enumelt, [[COPY_ARG]] : $T // CHECK-NOT: destroy_value [[ARG]] : $T // HECK: return [[OPTIONAL_ARG]] : $Optional // CHECK-LABEL: } // end sil function '$ss9f130_wrapyxSgxlF' func f130_wrap(_ x: T) -> T? { return x } func f150_anyArg(_: Any) {} // Tests init of opaque existentials // --- // CHECK-LABEL: sil hidden [ossa] @$ss15f160_callAnyArgyyF : $@convention(thin) () -> () { // CHECK: bb0: // HECK: [[INT_TYPE:%.*]] = metatype $@thin Builtin.Int64.Type // HECK: [[INT_LIT:%.*]] = integer_literal $Builtin.Builtin.Int64Literal, 42 // HECK: [[INT_ARG:%.*]] = apply %{{.*}}([[INT_LIT]], [[INT_TYPE]]) : $@convention(method) (Builtin.Builtin.Int64Literal, @thin Builtin.Int64.Type) -> Builtin.Int64 // HECK: [[INIT_OPAQUE:%.*]] = init_existential_value [[INT_ARG]] : $Builtin.Int64, $Builtin.Int64, $Any // HECK: apply %{{.*}}([[INIT_OPAQUE]]) : $@convention(thin) (@in_guaranteed Any) -> () // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss15f160_callAnyArgyyF' func f160_callAnyArg() { f150_anyArg(Int64(42)) } // Tests unconditional_checked_cast for opaque values // --- // CHECK-LABEL: sil hidden [ossa] @$ss18f170_force_convertxylF : $@convention(thin) () -> @out T { // CHECK: bb0: // HECK-NOT: alloc_stack // HECK: [[INT_TYPE:%.*]] = metatype $@thin Builtin.Int64.Type // HECK: [[INT_LIT:%.*]] = integer_literal $Builtin.Builtin.Int64Literal, 42 // HECK: [[INT_ARG:%.*]] = apply %{{.*}}([[INT_LIT]], [[INT_TYPE]]) : $@convention(method) (Builtin.Builtin.Int64Literal, @thin Builtin.Int64.Type) -> Builtin.Int64 // HECK: [[INT_CAST:%.*]] = unconditional_checked_cast_value [[INT_ARG]] : $Builtin.Int64 to $T // HECK: [[CAST_BORROW:%.*]] = begin_borrow [[INT_CAST]] : $T // HECK: [[RETURN_VAL:%.*]] = copy_value [[CAST_BORROW]] : $T // HECK: end_borrow [[CAST_BORROW]] : $T // HECK: destroy_value [[INT_CAST]] : $T // HECK: return [[RETURN_VAL]] : $T // CHECK-LABEL: } // end sil function '$ss18f170_force_convertxylF' func f170_force_convert() -> T { let x : T = Int64(42) as! T return x } // Tests supporting function for f190_return_foo_var - cast and return of protocol // --- // CHECK-LABEL: sil hidden [ossa] @$ss15f180_return_foos4FooP_pyF : $@convention(thin) () -> @out any FooP { // CHECK: bb0: // HECK: [[INT_LIT:%.*]] = integer_literal $Builtin.Builtin.Int64Literal, 42 // HECK: [[INT_ARG:%.*]] = apply %{{.*}}([[INT_LIT]], [[INT_TYPE]]) : $@convention(method) (Builtin.Builtin.Int64Literal, @thin Builtin.Int64.Type) -> Builtin.Int64 // HECK: [[INT_CAST:%.*]] = unconditional_checked_cast_value [[INT_ARG]] : $Builtin.Int64 to $any FooP // HECK: return [[INT_CAST]] : $any FooP // CHECK-LABEL: } // end sil function '$ss15f180_return_foos4FooP_pyF' func f180_return_foo() -> FooP { return Int64(42) as! FooP } var foo_var : FooP = f180_return_foo() // Tests return of global variables by doing a load of copy // --- // CHECK-LABEL: sil hidden [ossa] @$ss19f190_return_foo_vars4FooP_pyF : $@convention(thin) () -> @out any FooP { // CHECK: bb0: // HECK: [[GLOBAL:%.*]] = global_addr {{.*}} : $*any FooP // HECK: [[READ:%.*]] = begin_access [read] [dynamic] [[GLOBAL]] : $*any FooP // HECK: [[LOAD_GLOBAL:%.*]] = load [copy] [[READ]] : $*any FooP // HECK: return [[LOAD_GLOBAL]] : $any FooP // CHECK-LABEL: } // end sil function '$ss19f190_return_foo_vars4FooP_pyF' func f190_return_foo_var() -> FooP { return foo_var } // Tests deinit of opaque existentials // --- // CHECK-LABEL: sil hidden [ossa] @$ss16f200_use_foo_varyyF : $@convention(thin) () -> () { // CHECK: bb0: // HECK: [[GLOBAL:%.*]] = global_addr {{.*}} : $*FooP // HECK: [[READ:%.*]] = begin_access [read] [dynamic] [[GLOBAL]] : $*FooP // HECK: [[LOAD_GLOBAL:%.*]] = load [copy] [[READ]] : $*FooP // HECK: [[BORROW:%.*]] = begin_borrow [[LOAD_GLOBAL]] : $FooP // HECK: [[OPEN_VAR:%.*]] = open_existential_value [[BORROW]] : $FooP // HECK: [[WITNESS:%.*]] = witness_method $@opened // HECK: apply [[WITNESS]] // HECK: end_borrow [[BORROW]] // HECK: destroy_value [[LOAD_GLOBAL]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss16f200_use_foo_varyyF' func f200_use_foo_var() { foo_var.foo() } // Tests composition erasure of opaque existentials + copy into of opaques // --- // CHECK-LABEL: sil hidden [ossa] @$ss16f210_compErasureys5Error_psAB_s4FooPpF : $@convention(thin) (@in_guaranteed any Error & FooP) -> @owned any Error { // CHECK: bb0([[ARG:%.*]] : @guaranteed $any Error & FooP): // HECK: [[OPAQUE_ARG:%.*]] = open_existential_value [[ARG]] : $any Error & FooP to $@opened({{.*}}, any Error) Self & FooP // HECK: [[EXIST_BOX:%.*]] = alloc_existential_box $any Error, $@opened({{.*}}, any Error) Self & FooP // HECK: [[PROJ_BOX:%.*]] = project_existential_box $@opened({{.*}}, any Error) Self & FooP in [[EXIST_BOX]] // HECK: [[COPY_OPAQUE:%.*]] = copy_value [[OPAQUE_ARG]] : $@opened({{.*}}, any Error) Self & FooP // HECK: store [[COPY_OPAQUE]] to [init] [[PROJ_BOX]] : $*@opened({{.*}}, any Error) Self & FooP // CHECK-NOT: destroy_value [[ARG]] : $any Error & FooP // HECK: return [[EXIST_BOX]] : $any Error // CHECK-LABEL: } // end sil function '$ss16f210_compErasureys5Error_psAB_s4FooPpF' func f210_compErasure(_ x: FooP & Error) -> Error { return x } // Tests Implicit Value Construction under Opaque value mode // --- // f250_testBoxT continued Test Implicit Value Construction under Opaque value mode // --- // CHECK-LABEL: sil hidden [ossa] @$ss3BoxV1tAByxGx_tcfC : $@convention(method) (@in T, @thin Box.Type) -> @out Box { // CHECK: bb0([[ARG0:%.*]] : @owned $T, [[ARG1:%.*]] : $@thin Box.Type): // HECK: [[RETVAL:%.*]] = struct $Box ([[ARG0]] : $T) // HECK: return [[RETVAL]] : $Box // CHECK-LABEL: } // end sil function '$ss3BoxV1tAByxGx_tcfC' struct Box { let t: T } // CHECK-LABEL: sil hidden [ossa] @$ss13f250_testBoxTyyF : $@convention(thin) () -> () { // CHECK: bb0: // HECK: [[BOX_MTYPE:%.*]] = metatype $@thin Box.Type // HECK: [[MTYPE:%.*]] = metatype $@thin Builtin.Int64.Type // HECK: [[INTLIT:%.*]] = integer_literal $Builtin.Builtin.Int64Literal, 42 // HECK: [[AINT:%.*]] = apply {{.*}}([[INTLIT]], [[MTYPE]]) : $@convention(method) (Builtin.Builtin.Int64Literal, @thin Builtin.Int64.Type) -> Builtin.Int64 // HECK: apply {{.*}}([[AINT]], [[BOX_MTYPE]]) : $@convention(method) <τ_0_0> (@in τ_0_0, @thin Box<τ_0_0>.Type) -> @out Box<τ_0_0> // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss13f250_testBoxTyyF' func f250_testBoxT() { let _ = Box(t: Int64(42)) } enum AddressOnlyEnum { case nought case mere(EmptyP) case phantom(AddressOnlyStruct) } // Tests Address only enums // --- // CHECK-LABEL: sil hidden [ossa] @$ss15f260_AOnly_enumyys17AddressOnlyStructVF : $@convention(thin) (AddressOnlyStruct) -> () { // CHECK: bb0([[ARG:%.*]] : $AddressOnlyStruct): // HECK: [[MTYPE1:%.*]] = metatype $@thin AddressOnlyEnum.Type // HECK: [[APPLY1:%.*]] = apply {{.*}}([[MTYPE1]]) : $@convention(thin) (@thin AddressOnlyEnum.Type) -> @owned @callee_guaranteed (@in_guaranteed EmptyP) -> @out AddressOnlyEnum // HECK: destroy_value [[APPLY1]] // HECK: [[MTYPE2:%.*]] = metatype $@thin AddressOnlyEnum.Type // HECK: [[ENUM1:%.*]] = enum $AddressOnlyEnum, #AddressOnlyEnum.nought!enumelt // HECK: [[MTYPE3:%.*]] = metatype $@thin AddressOnlyEnum.Type // HECK: [[INIT_OPAQUE:%.*]] = init_existential_value [[ARG]] : $AddressOnlyStruct, $AddressOnlyStruct, $EmptyP // HECK: [[ENUM2:%.*]] = enum $AddressOnlyEnum, #AddressOnlyEnum.mere!enumelt, [[INIT_OPAQUE]] : $EmptyP // HECK: destroy_value [[ENUM2]] // HECK: [[MTYPE4:%.*]] = metatype $@thin AddressOnlyEnum.Type // HECK: [[ENUM3:%.*]] = enum $AddressOnlyEnum, #AddressOnlyEnum.phantom!enumelt, [[ARG]] : $AddressOnlyStruct // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss15f260_AOnly_enumyys17AddressOnlyStructVF' func f260_AOnly_enum(_ s: AddressOnlyStruct) { _ = AddressOnlyEnum.mere _ = AddressOnlyEnum.nought _ = AddressOnlyEnum.mere(s) _ = AddressOnlyEnum.phantom(s) } // Tests InjectOptional for opaque value types + conversion of opaque structs // --- // CHECK-LABEL: sil hidden [ossa] @$ss21f270_convOptAnyStructyys0dE0VACSgcF : $@convention(thin) (@guaranteed @callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct) -> () { // HECK: bb0([[ARG:%.*]] : $@callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[COPY_ARG]]) : $@convention(thin) (@in_guaranteed Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct) -> @out Optional // HECK: destroy_value [[PAPPLY]] : $@callee_guaranteed (@in_guaranteed Optional) -> @out Optional // HECK-NOT: destroy_value [[ARG]] : $@callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss21f270_convOptAnyStructyys0dE0VACSgcF' func f270_convOptAnyStruct(_ a1: @escaping (AnyStruct?) -> AnyStruct) { let _: (AnyStruct?) -> AnyStruct? = a1 } // f270_convOptAnyStruct continued Test: reabstraction thunk helper // --- // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$ss9AnyStructVSgABIegnr_A2CIegnr_TR : $@convention(thin) (@in_guaranteed Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct) -> @out Optional { // CHECK: bb0([[ARG0:%.*]] : @guaranteed $Optional, [[ARG1:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct): // HECK: [[APPLYARG:%.*]] = apply [[ARG1]]([[ARG0]]) : $@callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct // HECK: [[RETVAL:%.*]] = enum $Optional, #Optional.some!enumelt, [[APPLYARG]] : $AnyStruct // HECK: return [[RETVAL]] : $Optional // CHECK-LABEL: } // end sil function '$ss9AnyStructVSgABIegnr_A2CIegnr_TR' // Tests conversion between existential types // --- // CHECK-LABEL: sil hidden [ossa] @$ss21f280_convExistTrivialyys0D6StructVs1P_pcF : $@convention(thin) (@guaranteed @callee_guaranteed (@in_guaranteed any P) -> TrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed any P) -> TrivialStruct): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[COPY_ARG]]) : $@convention(thin) (@in_guaranteed P2, @guaranteed @callee_guaranteed (@in_guaranteed any P) -> TrivialStruct) -> @out P2 // HECK: destroy_value [[PAPPLY]] : $@callee_guaranteed (@in_guaranteed P2) -> @out P2 // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss21f280_convExistTrivialyys0D6StructVs1P_pcF' func f280_convExistTrivial(_ s: @escaping (P) -> TrivialStruct) { let _: (P2) -> P2 = s } // part of f280_convExistTrivial: conversion between existential types - reabstraction thunk // --- // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$ss1P_ps13TrivialStructVIegnd_s2P2_psAD_pIegnr_TR : $@convention(thin) (@in_guaranteed any P2, @guaranteed @callee_guaranteed (@in_guaranteed any P) -> TrivialStruct) -> @out any P2 { // CHECK: bb0([[ARG0:%.*]] : @guaranteed $any P2, [[ARG1:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed any P) -> TrivialStruct): // HECK: [[OPENED_ARG:%.*]] = open_existential_value [[ARG]] : $any P2 to $@opened({{.*}}, any P2) Self // HECK: [[COPIED_VAL:%.*]] = copy_value [[OPENED_ARG]] // HECK: [[INIT_P:%.*]] = init_existential_value [[COPIED_VAL]] : $@opened({{.*}}, any P2) Self, $@opened({{.*}}, any P2) Self, $any P // HECK: [[BORROWED_INIT_P:%.*]] = begin_borrow [[INIT_P]] // HECK: [[APPLY_P:%.*]] = apply [[ARG1]]([[BORROWED_INIT_P]]) : $@callee_guaranteed (@in_guaranteed any P) -> TrivialStruct // HECK: [[RETVAL:%.*]] = init_existential_value [[APPLY_P]] : $TrivialStruct, $TrivialStruct, $any P2 // HECK: end_borrow [[BORROWED_INIT_P]] // CHECK-NOT: destroy_value [[ARG0]] // HECK: return [[RETVAL]] : $any P2 // CHECK-LABEL: } // end sil function '$ss1P_ps13TrivialStructVIegnd_s2P2_psAD_pIegnr_TR' // Tests conversion between existential types - optionals case // --- // CHECK-LABEL: sil hidden [ossa] @$ss21f290_convOptExistTrivyys13TrivialStructVs1P_pSgcF : $@convention(thin) (@guaranteed @callee_guaranteed (@in_guaranteed Optional) -> TrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed Optional) -> TrivialStruct): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[COPY_ARG]]) : $@convention(thin) (Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> TrivialStruct) -> @out any P2 // HECK: destroy_value [[PAPPLY]] : $@callee_guaranteed (Optional) -> @out any P2 // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss21f290_convOptExistTrivyys13TrivialStructVs1P_pSgcF' func f290_convOptExistTriv(_ s: @escaping (P?) -> TrivialStruct) { let _: (TrivialStruct?) -> P2 = s } // part of f290_convOptExistTriv: conversion between existential types - reabstraction thunk - optionals case // --- // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$ss1P_pSgs13TrivialStructVIegnd_ADSgs2P2_pIegyr_TR : $@convention(thin) (Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> TrivialStruct) -> @out any P2 { // CHECK: bb0([[ARG0:%.*]] : $Optional, [[ARG1:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed Optional) -> TrivialStruct): // HECK: switch_enum [[ARG0]] : $Optional, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb1 // HECK: bb1: // HECK: [[ONONE:%.*]] = enum $Optional, #Optional.none!enumelt // HECK: br bb3([[ONONE]] : $Optional) // HECK: bb2([[OSOME:%.*]] : $TrivialStruct): // HECK: [[INIT_S:%.*]] = init_existential_value [[OSOME]] : $TrivialStruct, $TrivialStruct, $any P // HECK: [[ENUM_S:%.*]] = enum $Optional, #Optional.some!enumelt, [[INIT_S]] : $any P // HECK: br bb3([[ENUM_S]] : $Optional) // HECK: bb3([[OPT_S:%.*]] : $Optional): // HECK: [[BORROWED_OPT_S:%.*]] = begin_borrow [[OPT_S]] // HECK: [[APPLY_P:%.*]] = apply [[ARG1]]([[BORROWED_OPT_S]]) : $@callee_guaranteed (@in_guaranteed Optional) -> TrivialStruct // HECK: [[RETVAL:%.*]] = init_existential_value [[APPLY_P]] : $TrivialStruct, $TrivialStruct, $any P2 // HECK: return [[RETVAL]] : $any P2 // CHECK-LABEL: } // end sil function '$ss1P_pSgs13TrivialStructVIegnd_ADSgs2P2_pIegyr_TR' // Tests corner-case: reabstraction of an empty tuple to any // --- // CHECK-LABEL: sil hidden [ossa] @$ss20f300_convETupleToAnyyyyycF : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed () -> ()): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[COPY_ARG]]) : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Any // HECK: destroy_value [[PAPPLY]] : $@callee_guaranteed () -> @out Any // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss20f300_convETupleToAnyyyyycF' func f300_convETupleToAny(_ t: @escaping () -> ()) { let _: () -> Any = t } // f300_convETupleToAny continued Test: reabstraction of () to Any // --- // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIeg_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Any { // CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed () -> ()): // HECK: [[ASTACK:%.*]] = alloc_stack $Any // HECK: [[IADDR:%.*]] = init_existential_addr [[ASTACK]] : $*Any, $() // HECK: [[APPLYARG:%.*]] = apply [[ARG]]() : $@callee_guaranteed () -> () // HECK: [[LOAD_EXIST:%.*]] = load [trivial] [[IADDR]] : $*() // HECK: [[RETVAL:%.*]] = init_existential_value [[LOAD_EXIST]] : $(), $(), $Any // HECK: return [[RETVAL]] : $Any // CHECK-LABEL: } // end sil function '$sIeg_ypIegr_TR' // Tests corner-case: reabstraction of a non-empty tuple to any // --- // CHECK-LABEL: sil hidden [ossa] @$ss21f310_convnIntTupleAnyyyBi64__Bi64_tycF : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Builtin.Int64, Builtin.Int64)) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed () -> (Builtin.Int64, Builtin.Int64)): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[COPY_ARG]]) : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Builtin.Int64, Builtin.Int64)) -> @out Any // HECK: destroy_value [[PAPPLY]] : $@callee_guaranteed () -> @out Any // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss21f310_convnIntTupleAnyyyBi64__Bi64_tycF' func f310_convnIntTupleAny(_ t: @escaping () -> (Builtin.Int64, Builtin.Int64)) { let _: () -> Any = t } // f310_convIntTupleAny continued Test: reabstraction of non-empty tuple to Any // --- // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBi64_Bi64_Iegdd_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Builtin.Int64, Builtin.Int64)) -> @out Any { // CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed () -> (Builtin.Int64, Builtin.Int64)): // HECK: [[ASTACK:%.*]] = alloc_stack $Any // HECK: [[IADDR:%.*]] = init_existential_addr [[ASTACK]] : $*Any, $(Builtin.Int64, Builtin.Int64) // HECK: [[TADDR0:%.*]] = tuple_element_addr [[IADDR]] : $*(Builtin.Int64, Builtin.Int64), 0 // HECK: [[TADDR1:%.*]] = tuple_element_addr [[IADDR]] : $*(Builtin.Int64, Builtin.Int64), 1 // HECK: [[APPLYARG:%.*]] = apply [[ARG]]() : $@callee_guaranteed () -> (Builtin.Int64, Builtin.Int64) // HECK: [[TEXTRACT0:%.*]] = tuple_extract [[APPLYARG]] : $(Builtin.Int64, Builtin.Int64), 0 // HECK: [[TEXTRACT1:%.*]] = tuple_extract [[APPLYARG]] : $(Builtin.Int64, Builtin.Int64), 1 // HECK: store [[TEXTRACT0]] to [trivial] [[TADDR0]] : $*Builtin.Int64 // HECK: store [[TEXTRACT1]] to [trivial] [[TADDR1]] : $*Builtin.Int64 // HECK: [[LOAD_EXIST:%.*]] = load [trivial] [[IADDR]] : $*(Builtin.Int64, Builtin.Int64) // HECK: [[RETVAL:%.*]] = init_existential_value [[LOAD_EXIST]] : $(Builtin.Int64, Builtin.Int64), $(Builtin.Int64, Builtin.Int64), $Any // HECK: dealloc_stack [[ASTACK]] : $*Any // HECK: return [[RETVAL]] : $Any // CHECK-LABEL: } // end sil function '$sBi64_Bi64_Iegdd_ypIegr_TR' // Tests translating and imploding into Any under opaque value mode // --- // CHECK-LABEL: sil hidden [ossa] @$ss20f320_transImplodeAnyyyyypcF : $@convention(thin) (@guaranteed @callee_guaranteed (@in_guaranteed Any) -> ()) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed Any) -> ()): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[COPY_ARG]]) : $@convention(thin) (Builtin.Int64, Builtin.Int64, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> ()) -> () // HECK: destroy_value [[PAPPLY]] : $@callee_guaranteed (Builtin.Int64, Builtin.Int64) -> () // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss20f320_transImplodeAnyyyyypcF' func f320_transImplodeAny(_ t: @escaping (Any) -> ()) { let _: ((Builtin.Int64, Builtin.Int64)) -> () = t } // f320_transImplodeAny continued Test: reabstraction thunk // --- // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypIegn_Bi64_Bi64_Iegyy_TR : $@convention(thin) (Builtin.Int64, Builtin.Int64, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> ()) -> () { // CHECK: bb0([[ARG0:%.*]] : $Builtin.Int64, [[ARG1:%.*]] : $Builtin.Int64, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed Any) -> ()): // HECK: [[ASTACK:%.*]] = alloc_stack $Any // HECK: [[IADDR:%.*]] = init_existential_addr [[ASTACK]] : $*Any, $(Builtin.Int64, Builtin.Int64) // HECK: [[TADDR0:%.*]] = tuple_element_addr [[IADDR]] : $*(Builtin.Int64, Builtin.Int64), 0 // HECK: store [[ARG0]] to [trivial] [[TADDR0]] : $*Builtin.Int64 // HECK: [[TADDR1:%.*]] = tuple_element_addr [[IADDR]] : $*(Builtin.Int64, Builtin.Int64), 1 // HECK: store [[ARG1]] to [trivial] [[TADDR1]] : $*Builtin.Int64 // HECK: [[LOAD_EXIST:%.*]] = load [trivial] [[IADDR]] : $*(Builtin.Int64, Builtin.Int64) // HECK: [[INIT_OPAQUE:%.*]] = init_existential_value [[LOAD_EXIST]] : $(Builtin.Int64, Builtin.Int64), $(Builtin.Int64, Builtin.Int64), $Any // HECK: [[BORROWED_INIT_OPAQUE:%.*]] = begin_borrow [[INIT_OPAQUE]] // HECK: [[APPLYARG:%.*]] = apply [[ARG2]]([[BORROWED_INIT_OPAQUE]]) : $@callee_guaranteed (@in_guaranteed Any) -> () // HECK: dealloc_stack [[ASTACK]] : $*Any // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$sypIegn_Bi64_Bi64_Iegyy_TR' // Tests support for address only let closures under opaque value mode - they are not by-address anymore // --- // CHECK-LABEL: sil hidden [ossa] @$ss19f330_addrLetClosureyxxlF : $@convention(thin) (@in_guaranteed T) -> @out T { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] : $T // HECK: return [[COPY_ARG]] : $T // CHECK-LABEL: } // end sil function '$ss19f330_addrLetClosureyxxlF' func f330_addrLetClosure(_ x:T) -> T { return { { x }() }() } // Tests support for capture of a mutable opaque value type // --- // CHECK-LABEL: sil hidden [ossa] @$ss15f340_captureBoxyyF : $@convention(thin) () -> () { // CHECK: bb0: // HECK: [[ALLOC_OF_BOX:%.*]] = alloc_box ${ var EmptyP }, var, name "mutableAddressOnly" // HECK: [[PROJ_BOX:%.*]] = project_box [[ALLOC_OF_BOX]] // HECK: [[APPLY_FOR_BOX:%.*]] = apply %{{.*}}(%{{.*}}) : $@convention(method) (@thin AddressOnlyStruct.Type) -> AddressOnlyStruct // HECK: [[INIT_OPAQUE:%.*]] = init_existential_value [[APPLY_FOR_BOX]] : $AddressOnlyStruct, $AddressOnlyStruct, $EmptyP // HECK: store [[INIT_OPAQUE]] to [init] [[PROJ_BOX]] : $*EmptyP // HECK: [[BORROW_BOX:%.*]] = begin_borrow [[ALLOC_OF_BOX]] : ${ var EmptyP } // HECK: mark_function_escape [[PROJ_BOX]] : $*EmptyP // HECK: apply %{{.*}}([[BORROW_BOX]]) : $@convention(thin) (@guaranteed { var EmptyP }) -> () // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss15f340_captureBoxyyF' func f340_captureBox() { var mutableAddressOnly: EmptyP = AddressOnlyStruct() func captureEverything() { genericInout(&mutableAddressOnly) } captureEverything() } // Tests support for guards and indirect enums for opaque values // --- // CHECK-LABEL: sil hidden [ossa] @$ss14f360_guardEnumyys08IndirectC0OyxGlF : $@convention(thin) (@guaranteed IndirectEnum) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $IndirectEnum): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: switch_enum [[COPY_ARG]] : $IndirectEnum, case #IndirectEnum.Node!enumelt: [[NODE_BB:bb[0-9]+]], case #IndirectEnum.Nil!enumelt: [[NIL_BB:bb[0-9]+]] // // HECK: [[NIL_BB]]: // HECK: br [[NIL_TRAMPOLINE:bb[0-9]+]] // // HECK: [[NIL_TRAMPOLINE]]: // HECK: br [[EPILOG_BB:bb[0-9]+]] // // HECK: [[NODE_BB]]([[EARG:%.*]] : $<τ_0_0> { var τ_0_0 } ): // HECK: [[PROJ_BOX:%.*]] = project_box [[EARG]] // HECK: [[LOAD_BOX:%.*]] = load [take] [[PROJ_BOX]] : $*T // HECK: [[COPY_BOX:%.*]] = copy_value [[LOAD_BOX]] : $T // HECK: destroy_value [[EARG]] // HECK: br [[CONT_BB:bb[0-9]+]] // // HECK: [[CONT_BB]]: // HECK: destroy_value [[COPY_BOX]] // HECK: br [[EPILOG_BB]] // // HECK: [[EPILOG_BB]]: // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss14f360_guardEnumyys08IndirectC0OyxGlF' func f360_guardEnum(_ e: IndirectEnum) { do { guard case .Node(let x) = e else { return } _ = x } } // Tests contextual init() of opaque value types // --- // CHECK-LABEL: sil hidden [ossa] @$ss17f370_optToOptCastyxSgABlF : $@convention(thin) (@in_guaranteed Optional) -> @out Optional { // CHECK: bb0([[ARG:%.*]] : @guaranteed $Optional): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // CHECK-NOT: destroy_value [[ARG]] // HECK: return [[COPY_ARG]] : $Optional // CHECK-LABEL: } // end sil function '$ss17f370_optToOptCastyxSgABlF' func f370_optToOptCast(_ x : T!) -> T? { return x } // Tests casting optional opaques to optional opaques // --- // CHECK-LABEL: sil hidden [ossa] @$ss19f380_contextualInityyBi64_SgF : $@convention(thin) (Optional) -> () { // CHECK: bb0([[ARG:%.*]] : $Optional): // HECK: [[ALLOC_OF_BOX:%.*]] = alloc_box ${ var Optional }, var // HECK: [[PROJ_BOX:%.*]] = project_box [[ALLOC_OF_BOX]] // HECK: store [[ARG]] to [trivial] [[PROJ_BOX]] : $*Optional // HECK: destroy_value [[ALLOC_OF_BOX]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss19f380_contextualInityyBi64_SgF' func f380_contextualInit(_ a : Builtin.Int64?) { var x: Builtin.Int64? = a genericInout(&x) _ = x } // Tests opaque call result types // --- // CHECK-LABEL: sil hidden [ossa] @$ss19f390_addrCallResultyyxycSglF : $@convention(thin) (@guaranteed Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for >) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for >): // HECK: [[ALLOC_OF_BOX:%.*]] = alloc_box $<τ_0_0> { var Optional<τ_0_0> } // HECK: [[PROJ_BOX:%.*]] = project_box [[ALLOC_OF_BOX]] // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: [[SENUM:%.*]] = select_enum [[COPY_ARG]] // HECK: cond_br [[SENUM]], bb3, bb1 // HECK: bb1: // HECK: br bb2 // HECK: bb2: // HECK: [[ONONE:%.*]] = enum $Optional, #Optional.none!enumelt // HECK: br bb4([[ONONE]] : $Optional) // HECK: bb4(%{{.*}} : $Optional): // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss19f390_addrCallResultyyxycSglF' func f390_addrCallResult(_ f: (() -> T)?) { var x = f?() genericInout(&x) _ = x } // Tests reabstraction / partial apply of protocols under opaque value mode // --- // CHECK-LABEL: sil hidden [ossa] @$ss16f400_maybeCloneP1cys8Clonable_p_tF : $@convention(thin) (@in_guaranteed any Clonable) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $any Clonable): // HECK: [[OPEN_ARG:%.*]] = open_existential_value [[ARG]] : $any Clonable // HECK: [[APPLY_OPAQUE:%.*]] = apply %{{.*}}<@opened({{.*}}, any Clonable) Self>([[OPEN_ARG]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed () -> @out Optional<τ_0_0> // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}<@opened({{.*}}, any Clonable) Self>([[APPLY_OPAQUE]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out Optional<τ_0_0>) -> @out Optional // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss16f400_maybeCloneP1cys8Clonable_p_tF' func f400_maybeCloneP(c: Clonable) { let _: () -> Clonable? = c.maybeClone } // Tests global opaque values / subscript rvalues // --- // CHECK-LABEL: sil hidden [ossa] @$ss20f410_globalRvalueGetyBi64_Bi64_F : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 { // CHECK: bb0([[ARG:%.*]] : $Builtin.Int64): // HECK: [[GLOBAL_ADDR:%.*]] = global_addr @$s20opaque_values_silgen16subscriptableGetAA013SubscriptableE0_pvp : $*SubscriptableGet // HECK: [[READ:%.*]] = begin_access [read] [dynamic] [[GLOBAL_ADDR]] : $*SubscriptableGet // HECK: [[OPEN_ARG:%.*]] = open_existential_addr immutable_access [[READ]] : $*SubscriptableGet to $*@opened // HECK: [[GET_OPAQUE:%.*]] = load [copy] [[OPEN_ARG]] : $*@opened // HECK: [[RETVAL:%.*]] = apply %{{.*}}<@opened({{.*}}, SubscriptableGet) Self>([[ARG]], [[GET_OPAQUE]]) : $@convention(witness_method: SubscriptableGet) <τ_0_0 where τ_0_0 : SubscriptableGet> (Builtin.Int64, @in_guaranteed τ_0_0) -> Builtin.Int64 // HECK: destroy_value [[GET_OPAQUE]] // HECK: return [[RETVAL]] : $Builtin.Int64 // CHECK-LABEL: } // end sil function '$ss20f410_globalRvalueGetyBi64_Bi64_F' func f410_globalRvalueGet(_ i : Builtin.Int64) -> Builtin.Int64 { return subscriptableGet![i] } // Tests global opaque values / subscript lvalues // --- // CHECK-LABEL: sil hidden [ossa] @$ss20f420_globalLvalueGetyBi64_SgBi64_F : $@convention(thin) (Builtin.Int64) -> Optional { // CHECK: bb0([[ARG:%.*]] : $Builtin.Int64): // HECK: [[GLOBAL_ADDR:%.*]] = global_addr @$s20opaque_values_silgen19subscriptableGetSetAA013SubscriptableeF0_pvp : $*SubscriptableGetSet // HECK: [[READ:%.*]] = begin_access [read] [dynamic] [[GLOBAL_ADDR]] : $*SubscriptableGetSet // HECK: [[OPEN_ARG:%.*]] = open_existential_addr immutable_access [[READ]] : $*SubscriptableGetSet to $*@opened // HECK: [[GET_OPAQUE:%.*]] = load [copy] [[OPEN_ARG]] : $*@opened // HECK: [[RETVAL:%.*]] = apply %{{.*}}<@opened({{.*}}, SubscriptableGetSet) Self>([[ARG]], [[GET_OPAQUE]]) : $@convention(witness_method: SubscriptableGetSet) <τ_0_0 where τ_0_0 : SubscriptableGetSet> (Builtin.Int64, @in_guaranteed τ_0_0) -> Builtin.Int64 // HECK: destroy_value [[GET_OPAQUE]] // HECK: return [[RETVAL]] : $Builtin.Int64 // CHECK-LABEL: } // end sil function '$ss20f420_globalLvalueGetyBi64_SgBi64_F' func f420_globalLvalueGet(_ i : Builtin.Int64) -> Builtin.Int64? { return subscriptableGetSet![i] } // Tests tuple transformation // --- // CHECK-LABEL: sil hidden [ossa] @$ss21f430_callUnreachableF1tyx_tlF : $@convention(thin) (@in_guaranteed T) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // HECK: [[APPLY_T:%.*]] = apply %{{.*}}<((T) -> (), T)>() : $@convention(thin) <τ_0_0> () -> @out Optional<(Builtin.Int64, τ_0_0)> // HECK: switch_enum [[APPLY_T]] : $Optional<(Builtin.Int64, (@callee_guaranteed (@in_guaranteed T) -> @out (), T))>, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb1 // HECK: bb2([[ENUMARG:%.*]] : $(Builtin.Int64, (@callee_guaranteed (@in_guaranteed T) -> @out (), T))): // HECK: ([[TELEM0:%.*]], [[TELEM1:%.*]]) = destructure_tuple [[ENUMARG]] : $(Builtin.Int64, (@callee_guaranteed (@in_guaranteed T) -> @out (), T)) // HECK: ([[TELEM10:%.*]], [[TELEM11:%.*]]) = destructure_tuple [[TELEM1]] : $(@callee_guaranteed (@in_guaranteed T) -> @out (), T) // HECK: [[PAPPLY:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[TELEM10]]) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> @out ()) -> () // HECK: [[NEWT0:%.*]] = tuple ([[PAPPLY]] : $@callee_guaranteed (@in_guaranteed T) -> (), [[TELEM11]] : $T) // HECK: [[NEWT1:%.*]] = tuple ([[TELEM0]] : $Builtin.Int64, [[NEWT0]] : $(@callee_guaranteed (@in_guaranteed T) -> (), T)) // HECK: [[NEWENUM:%.*]] = enum $Optional<(Builtin.Int64, (@callee_guaranteed (@in_guaranteed T) -> (), T))>, #Optional.some!enumelt, [[NEWT1]] : $(Builtin.Int64, (@callee_guaranteed (@in_guaranteed T) -> (), T)) // HECK: br bb3([[NEWENUM]] : $Optional<(Builtin.Int64, (@callee_guaranteed (@in_guaranteed T) -> (), T))>) // HECK: bb3([[ENUMIN:%.*]] : $Optional<(Builtin.Int64, (@callee_guaranteed (@in_guaranteed T) -> (), T))>): // HECK: destroy_value [[ENUMIN]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss21f430_callUnreachableF1tyx_tlF' func f430_callUnreachableF(t: T) { let _: (Builtin.Int64, ((T) -> (), T))? = unreachableF() } // Further testing for conditional checked cast under opaque value mode - make sure we don't create a buffer for results // --- // CHECK-LABEL: sil hidden [ossa] @$ss20f440_cleanupEmissionyyxlF : $@convention(thin) (@in_guaranteed T) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: checked_cast_value_br [[COPY_ARG]] : $T to $EmptyP, bb2, bb1 // // HECK: bb2([[PTYPE:%.*]] : $EmptyP): // HECK: [[PSOME:%.*]] = enum $Optional, #Optional.some!enumelt, [[PTYPE]] : $EmptyP // HECK: br bb3([[PSOME]] : $Optional) // // HECK: bb3([[ENUMRES:%.*]] : $Optional): // HECK: switch_enum [[ENUMRES]] : $Optional, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]] // // HECK: [[NONE_BB]]: // HECK: br [[NONE_TRAMPOLINE:bb[0-9]+]] // // HECK: [[NONE_TRAMPOLINE]]: // HECK: br [[EPILOG_BB:bb[0-9]+]] // // HECK: [[SOME_BB]]([[ENUMRES2:%.*]] : $EmptyP): // HECK: br [[CONT_BB:bb[0-9]+]] // // HECK: [[CONT_BB]]: // HECK: destroy_value [[ENUMRES2]] // HECK: br [[EPILOG_BB]] // // HECK: [[EPILOG_BB]]: // CHECK-NOT: destroy_value [[ARG]] // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss20f440_cleanupEmissionyyxlF' func f440_cleanupEmission(_ x: T) { guard let x2 = x as? EmptyP else { return } _ = x2 } // Test emitNativeToCBridgedNonoptionalValue. // --- // CHECK-objc-LABEL: sil hidden [ossa] @$ss14f470_nativeToC7fromAnyyXlyp_tF : $@convention(thin) (@in_guaranteed Any) -> @owned AnyObject { // CHECK-objc: bb0(%0 : $Any): // CHECK-objc: [[BORROW:%.*]] = begin_borrow %0 : $Any // CHECK-objc: [[SRC:%.*]] = copy_value [[BORROW]] : $Any // CHECK-objc: [[OPEN:%.*]] = open_existential_opaque [[SRC]] : $Any to $@opened // CHECK-objc: [[COPY:%.*]] = copy_value [[OPEN]] : $@opened // CHECK-objc: [[F:%.*]] = function_ref @$sf27_bridgeAnythingToObjectiveCyyXlxlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject // CHECK-objc: [[RET:%.*]] = apply [[F]]<@opened("{{.*}}", Any) Self>([[COPY]]) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject // CHECK-objc: destroy_value [[SRC]] : $Any // CHECK-objc: destroy_value %0 : $Any // CHECK-objc: return [[RET]] : $AnyObject // CHECK-objc-LABEL: } // end sil function '$ss14f470_nativeToC7fromAnyyXlyp_tF' #if _runtime(_ObjC) func f470_nativeToC(fromAny any: Any) -> AnyObject { return any as AnyObject } #endif // Test emitOpenExistential. // --- // CHECK-LABEL: sil hidden [ossa] @$ss13f480_getError04someC0yps0C0_p_tF : $@convention(thin) (@guaranteed any Error) -> @out Any { // CHECK: bb0([[ARG:%.*]] : @guaranteed $any Error): // HECK: [[VAL:%.*]] = open_existential_box_value [[ARG]] : $any Error to $@opened("{{.*}}", any Error) Self // HECK: [[COPY:%.*]] = copy_value [[VAL]] : $@opened("{{.*}}", any Error) Self // HECK: [[ANY:%.*]] = init_existential_value [[COPY]] : $@opened("{{.*}}", any Error) Self, $@opened("{{.*}}", any Error) Self, $Any // CHECK-NOT: destroy_value [[ARG]] : $any Error // HECK: return [[ANY]] : $Any // CHECK-LABEL: } // end sil function '$ss13f480_getError04someC0yps0C0_p_tF' func f480_getError(someError: Error) -> Any { return someError } // Test visitBindOptionalExpr // --- // CHECK-LABEL: sil hidden [ossa] @$ss15f500_getAnyHashys1P_pSgs14ConvertibleToP_pSgF : $@convention(thin) (@in_guaranteed Optional) -> @out Optional { // CHECK: bb0(%0 : @guaranteed $Optional): // HECK: [[COPY:%.*]] = copy_value [[ARG]] : $Optional // HECK: [[DATA:%.*]] = unchecked_enum_data [[COPY]] : $Optional, #Optional.some!enumelt // HECK: [[BORROW_DATA:%.*]] = begin_borrow [[DATA]] : $any ConvertibleToP // HECK: [[VAL:%.*]] = open_existential_value [[BORROW_DATA]] : $any ConvertibleToP to $@opened("{{.*}}", any ConvertibleToP) Self // HECK: [[WT:%.*]] = witness_method $@opened("{{.*}}", any ConvertibleToP) Self, #ConvertibleToP.asP : (Self) -> () -> P, [[VAL]] : $@opened("{{.*}}", any ConvertibleToP) Self : $@convention(witness_method: ConvertibleToP) <τ_0_0 where τ_0_0 : ConvertibleToP> (@in_guaranteed τ_0_0) -> @out any P // HECK: [[AS_P:%.*]] = apply [[WT]]<@opened("{{.*}}", any ConvertibleToP) Self>([[VAL]]) : $@convention(witness_method: ConvertibleToP) <τ_0_0 where τ_0_0 : ConvertibleToP> (@in_guaranteed τ_0_0) -> @out any P // HECK: [[ENUM:%.*]] = enum $Optional, #Optional.some!enumelt, [[AS_P]] : $any P // HECK: destroy_value [[DATA]] : $any ConvertibleToP // HECK: br bb{{.*}}([[ENUM]] : $Optional) // HECK: } // end sil function '$ss15f500_getAnyHashys1P_pSgs14ConvertibleToP_pSgF' func f500_getAnyHash(_ value: ConvertibleToP?) -> P? { return value?.asP() } public protocol FooPP { func foo() -> Self } // Test emitting a protocol witness for a method (with @in_guaranteed self) on a dependent generic type. // --- // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$ss15f510_OpaqueSelfVyxGs5FooPPssADP3fooxyFTW : $@convention(witness_method: FooPP) <τ_0_0> (@in_guaranteed f510_OpaqueSelf<τ_0_0>) -> @out f510_OpaqueSelf<τ_0_0> { // CHECK: bb0(%0 : @guaranteed $f510_OpaqueSelf<τ_0_0>): // HECK: [[FN:%.*]] = function_ref @$s20opaque_values_silgen21f510_OpaqueSelfV3fooACyxGyF : $@convention(method) <τ_0_0> (@in_guaranteed f510_OpaqueSelf<τ_0_0>) -> @out f510_OpaqueSelf<τ_0_0> // HECK: [[RESULT:%.*]] = apply [[FN]]<τ_0_0>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed f510_OpaqueSelf<τ_0_0>) -> @out f510_OpaqueSelf<τ_0_0> // HECK: return [[RESULT]] : $f510_OpaqueSelf<τ_0_0> // CHECK-LABEL: } // end sil function '$ss15f510_OpaqueSelfVyxGs5FooPPssADP3fooxyFTW' struct f510_OpaqueSelf : FooPP { var x: Base func foo() -> f510_OpaqueSelf { return self } } // Tests conditional value casts and correspondingly generated reabstraction thunk, with types // --- // CHECK-LABEL: sil hidden [ossa] @$ss17f520_condTFromAnyyyyp_xtlF : $@convention(thin) (@in_guaranteed Any, @in_guaranteed T) -> () { // CHECK: bb0([[ARG0:%.*]] : @guaranteed $Any, [[ARG1:%.*]] : @guaranteed $T): // HECK: [[COPY_ARG:%.*]] = copy_value [[ARG]] // HECK: checked_cast_value_br [[COPY_ARG]] : $Any to $@callee_guaranteed (@in_guaranteed (Builtin.Int64, T)) -> @out (Builtin.Int64, T), bb2, bb1 // HECK: bb2([[THUNK_PARAM:%.*]] : $@callee_guaranteed (@in_guaranteed (Builtin.Int64, T)) -> @out (Builtin.Int64, T)): // HECK: [[THUNK_REF:%.*]] = function_ref @{{.*}} : $@convention(thin) <τ_0_0> (Builtin.Int64, @in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed (Builtin.Int64, τ_0_0)) -> @out (Builtin.Int64, τ_0_0)) -> (Builtin.Int64, @out τ_0_0) // HECK: partial_apply [callee_guaranteed] [[THUNK_REF]]([[THUNK_PARAM]]) // CHECK: bb6: // HECK: return %{{.*}} : $() // CHECK-LABEL: } // end sil function '$ss17f520_condTFromAnyyyyp_xtlF' func f520_condTFromAny(_ x: Any, _ y: T) { if let f = x as? (Int64, T) -> (Int64, T) { _ = f(Int64(42), y) } } // Make sure that we insert a destroy of the box even though we used an Builtin.Int64 type. // CHECK-LABEL: sil [ossa] @$ss16f530_assignToVaryyF : $@convention(thin) () -> () { // CHECK: bb0: // HECK: [[Y_BOX:%.*]] = alloc_box ${ var Builtin.Int64 }, var, name "y" // HECK: [[PROJECT_Y_BOX:%.*]] = project_box [[Y_BOX]] : ${ var Builtin.Int64 }, 0 // HECK: [[X_BOX:%.*]] = alloc_box ${ var Any }, var, name "x" // HECK: [[PROJECT_X_BOX:%.*]] = project_box [[X_BOX]] : ${ var Any }, 0 // HECK: [[ACCESS_PROJECT_Y_BOX:%.*]] = begin_access [read] [unknown] [[PROJECT_Y_BOX]] : $*Builtin.Int64 // HECK: [[Y:%.*]] = load [trivial] [[ACCESS_PROJECT_Y_BOX]] : $*Builtin.Int64 // HECK: [[Y_ANY_FOR_X:%.*]] = init_existential_value [[Y]] : $Builtin.Int64, $Builtin.Int64, $Any // HECK: store [[Y_ANY_FOR_X]] to [init] [[PROJECT_X_BOX]] // HECK: [[ACCESS_PROJECT_Y_BOX:%.*]] = begin_access [read] [unknown] [[PROJECT_Y_BOX]] : $*Builtin.Int64 // HECK: [[Y:%.*]] = load [trivial] [[ACCESS_PROJECT_Y_BOX]] : $*Builtin.Int64 // HECK: [[Y_ANY_FOR_Z:%.*]] = init_existential_value [[Y]] : $Builtin.Int64, $Builtin.Int64, $Any // HECK: destroy_value [[Y_ANY_FOR_Z]] // HECK: destroy_value [[X_BOX]] // HECK: destroy_value [[Y_BOX]] // HECK: } // end sil function '$ss16f530_assignToVaryyF' public func f530_assignToVar() { var y: Int64 = 3 var x: Any = y let z: Any = y genericInout(&y) genericInout(&x) _ = z } // Test open_existential_value ownership // --- // CHECK-LABEL: sil [ossa] @$ss16f540_takeDecoder4fromBi1_s0C0_p_tKF : $@convention(thin) (@in_guaranteed any Decoder) -> (Builtin.Int1, @error any Error) { // CHECK: bb0(%0 : @guaranteed $any Decoder): // HECK: [[OPENED:%.*]] = open_existential_value %0 : $any Decoder to $@opened("{{.*}}", any Decoder) Self // HECK: [[WT:%.*]] = witness_method $@opened("{{.*}}", any Decoder) Self, #Decoder.unkeyedContainer : (Self) -> () throws -> UnkeyedDecodingContainer, %3 : $@opened("{{.*}}", any Decoder) Self : $@convention(witness_method: Decoder) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error any Error) // HECK: try_apply [[WT]]<@opened("{{.*}}", any Decoder) Self>([[OPENED]]) : $@convention(witness_method: Decoder) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error any Error), normal bb2, error bb1 // // CHECK:bb{{.*}}([[RET1:%.*]] : @owned $any UnkeyedDecodingContainer): // HECK: [[BORROW2:%.*]] = begin_borrow [lexical] [var_decl] [[RET1]] : $any UnkeyedDecodingContainer // HECK: [[OPENED2:%.*]] = open_existential_value [[BORROW2]] : $any UnkeyedDecodingContainer to $@opened("{{.*}}", any UnkeyedDecodingContainer) Self // HECK: [[WT2:%.*]] = witness_method $@opened("{{.*}}", any UnkeyedDecodingContainer) Self, #UnkeyedDecodingContainer.isAtEnd!getter : (Self) -> () -> Builtin.Int1, [[OPENED2]] : $@opened("{{.*}}", UnkeyedDecodingContainer) Self : $@convention(witness_method: UnkeyedDecodingContainer) <τ_0_0 where τ_0_0 : UnkeyedDecodingContainer> (@in_guaranteed τ_0_0) -> Builtin.Int1 // HECK: [[RET2:%.*]] = apply [[WT2]]<@opened("{{.*}}", any UnkeyedDecodingContainer) Self>([[OPENED2]]) : $@convention(witness_method: UnkeyedDecodingContainer) <τ_0_0 where τ_0_0 : UnkeyedDecodingContainer> (@in_guaranteed τ_0_0) -> Builtin.Int1 // HECK: end_borrow [[BORROW2]] : $any UnkeyedDecodingContainer // HECK: destroy_value [[RET1]] : $any UnkeyedDecodingContainer // CHECK-NOT: destroy_value %0 : $any Decoder // HECK: return [[RET2]] : $Builtin.Int1 // CHECK-LABEL: } // end sil function '$ss16f540_takeDecoder4fromBi1_s0C0_p_tKF' public func f540_takeDecoder(from decoder: Decoder) throws -> Builtin.Int1 { let container = try decoder.unkeyedContainer() return container.isAtEnd }