// RUN: %target-swift-emit-silgen -sil-verify-all %s | %FileCheck %s //////////////////////// // MARK: Declarations // //////////////////////// public class Klass {} public struct NonTrivialStruct { var k = Klass() func doSomethingDefault() {} borrowing func doSomethingBorrowing() {} mutating func doSomethingMutating() {} //consuming func doSomethingConsuming() {} } public protocol P { static var value: Self { get } } public struct GenericNonTrivialStruct { var t = T.value func doSomethingDefault() {} borrowing func doSomethingBorrowing() {} } enum AddressOnlyEnum { case x(NonTrivialStruct) case y(T) } enum LoadableEnum { case x(NonTrivialStruct) case y(Int) } func borrowValDefault(_ x: NonTrivialStruct) {} func borrowValBorrowing(_ x: borrowing NonTrivialStruct) {} func borrowValDefault(_ x: GenericNonTrivialStruct) {} func borrowValBorrowing(_ x: borrowing GenericNonTrivialStruct) {} //func consumeValOwned(_ x: __owned NonTrivialStruct) {} //func consumeValConsuming(_ x: consuming NonTrivialStruct) {} //func consumeValOwned(_ x: __owned GenericNonTrivialStruct) {} //func consumeValConsuming(_ x: consuming GenericNonTrivialStruct) {} //////////////////////// // MARK: Simple Tests // //////////////////////// // CHECK: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters11testConsumeyyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @guaranteed $NonTrivialStruct): // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] // CHECK: [[COPY2:%.*]] = copy_value [[BORROW]] // CHECK: [[MOVE:%.*]] = move_value [[COPY2]] // CHECK: destroy_value [[MOVE]] // CHECK: end_borrow [[BORROW]] // // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] // CHECK: [[EXT:%.*]] = struct_extract [[BORROW]] // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable [guaranteed] [[EXT]] // CHECK: [[COPY:%.*]] = copy_value [[UNWRAP]] // CHECK: destroy_value [[COPY]] // CHECK: end_borrow [[BORROW]] // // CHECK: destroy_value [[CHECK]] // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters11testConsumeyyAA16NonTrivialStructVF' func testConsume(_ x: borrowing NonTrivialStruct) { let _ = x let _ = x.k } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters7testUseyyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @guaranteed $NonTrivialStruct): // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] // CHECK: end_borrow [[BORROW]] // CHECK: destroy_value [[CHECK]] // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters7testUseyyAA16NonTrivialStructVF' func testUse(_ x: borrowing NonTrivialStruct) { _ = x } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters24testCallBorrowValDefaultyyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @guaranteed $NonTrivialStruct): // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable [guaranteed] [[BORROW]] // CHECK: apply {{%.*}}([[UNWRAP]]) // CHECK: end_borrow [[BORROW]] // CHECK: destroy_value [[CHECK]] // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters24testCallBorrowValDefaultyyAA16NonTrivialStructVF' func testCallBorrowValDefault(_ x: borrowing NonTrivialStruct) { borrowValDefault(x) } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters26testCallBorrowValBorrowingyyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @guaranteed $NonTrivialStruct): // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] func testCallBorrowValBorrowing(_ x: borrowing NonTrivialStruct) { borrowValBorrowing(x) } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters25testCallMethodSelfDefaultyyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @guaranteed $NonTrivialStruct): // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable [guaranteed] [[BORROW]] // CHECK: apply {{%.*}}([[UNWRAP]]) // CHECK: end_borrow [[BORROW]] // CHECK: destroy_value [[CHECK]] // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters25testCallMethodSelfDefaultyyAA16NonTrivialStructVF' func testCallMethodSelfDefault(_ x: borrowing NonTrivialStruct) { x.doSomethingDefault() } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters27testCallMethodSelfBorrowingyyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable [guaranteed] [[BORROW]] // TODO: This should be passed directly without a conversion. // CHECK: apply {{%.*}}([[UNWRAP]]) // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters27testCallMethodSelfBorrowingyyAA16NonTrivialStructVF' func testCallMethodSelfBorrowing(_ x: borrowing NonTrivialStruct) { x.doSomethingBorrowing() } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters19testEscapingClosureyyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @guaranteed $NonTrivialStruct): // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[COPY2:%.*]] = copy_value [[CHECK]] // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable [owned] [[COPY2]] // CHECK: partial_apply [callee_guaranteed] {{%.*}}([[UNWRAP]]) // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters19testEscapingClosureyyAA16NonTrivialStructVF' func testEscapingClosure(_ x: borrowing NonTrivialStruct) { var f: () -> () = {} f = { _ = x } _ = f } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters22testNonEscapingClosureyyAA0E13TrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @guaranteed $NonTrivialStruct): // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[COPY2:%.*]] = copy_value [[CHECK]] // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable [owned] [[COPY2]] // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[UNWRAP]]) // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters22testNonEscapingClosureyyAA0E13TrivialStructVF' func testNonEscapingClosure(_ x: borrowing NonTrivialStruct) { func useNonEscaping(_ f: () -> ()) {} useNonEscaping { _ = x } } // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters36testLoadableBorrowingConsumeOperatoryyAA16NonTrivialStructVF : $@convention(thin) (@guaranteed NonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper [guaranteed] // CHECK: [[COPY:%.*]] = copy_value [[WRAP]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]] // CHECK: [[BORROW:%.*]] = begin_borrow [[CHECK]] // CHECK: [[COPY2:%.*]] = copy_value [[BORROW]] // CHECK: [[MOVE:%.*]] = move_value [allows_diagnostics] [[COPY2]] // CHECK: destroy_value [[MOVE]] // CHECK: end_borrow [[BORROW]] // CHECK: destroy_value [[CHECK]] // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters36testLoadableBorrowingConsumeOperatoryyAA16NonTrivialStructVF' func testLoadableBorrowingConsumeOperator(_ x: borrowing NonTrivialStruct) { _ = consume x } func testLoadableBorrowingEnum(_ x: borrowing LoadableEnum) { switch x { case let .x(y): _ = y break case .y: break } } ////////////////////////////////////////////// // MARK: Simple AddressOnly Borrowing Tests // ////////////////////////////////////////////// // CHECK-LABEL: sil hidden [ossa] @$s35noimplicitcopy_borrowing_parameters31testAddressOnlyBorrowingConsumeyyAA23GenericNonTrivialStructVyxGAA1PRzlF : $@convention(thin) (@in_guaranteed GenericNonTrivialStruct) -> () { // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy // CHECK: [[WRAP:%.*]] = copyable_to_moveonlywrapper_addr [[ARG]] // CHECK: [[CHECK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[WRAP]] // CHECK: [[STACK:%.*]] = alloc_stack // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable_addr [[CHECK]] // CHECK: copy_addr [[UNWRAP]] to [init] [[STACK]] // CHECK: destroy_addr [[STACK]] // CHECK: [[UNWRAP:%.*]] = moveonlywrapper_to_copyable_addr [[CHECK]] // TODO: We probably want the unwrap to be on the struct_element_addr, not the other way around. // CHECK: [[GEP:%.*]] = struct_element_addr [[UNWRAP]] // CHECK: [[STACK:%.*]] = alloc_stack // CHECK: copy_addr [[GEP]] to [init] [[STACK]] // CHECK: destroy_addr [[STACK]] // CHECK: } // end sil function '$s35noimplicitcopy_borrowing_parameters31testAddressOnlyBorrowingConsumeyyAA23GenericNonTrivialStructVyxGAA1PRzlF' func testAddressOnlyBorrowingConsume(_ x: borrowing GenericNonTrivialStruct) { let _ = x let _ = x.t } func testAddressOnlyBorrowingConsume2(_ x: borrowing GenericNonTrivialStruct) { var y = x y = x _ = y } func testAddressOnlyBorrowingConsume3(_ x: borrowing GenericNonTrivialStruct) { let y = x _ = y } func testAddressOnlyBorrowingUse(_ x: borrowing GenericNonTrivialStruct) { _ = x } func testAddressOnlyBorrowingUseAndConsume(_ x: borrowing GenericNonTrivialStruct) { borrowValDefault(x) let _ = x } func testAddressOnlyBorrowingCallBorrowValDefault(_ x: borrowing GenericNonTrivialStruct) { borrowValDefault(x) } func testAddressOnlyBorrowingCallBorrowValBorrowing(_ x: borrowing GenericNonTrivialStruct) { borrowValBorrowing(x) } func testAddressOnlyBorrowingCallMethodSelfDefault(_ x: borrowing GenericNonTrivialStruct) { x.doSomethingDefault() } func testAddressOnlyBorrowingCallMethodSelfBorrowing(_ x: borrowing GenericNonTrivialStruct) { x.doSomethingBorrowing() } func testAddressOnlyBorrowingEscapingClosure(_ x: borrowing GenericNonTrivialStruct) { var f: () -> () = {} f = { _ = x } _ = f } func testAddressOnlyBorrowingNonEscapingClosure(_ x: borrowing GenericNonTrivialStruct) { func useNonEscaping(_ f: () -> ()) {} useNonEscaping { _ = x } } func testAddressOnlyBorrowingCast(_ x: borrowing GenericNonTrivialStruct) { let _ = x as Any } func testAddressOnlyBorrowingCastCheck(_ x: borrowing GenericNonTrivialStruct) { if x is Any { } } func testAddressOnlyBorrowingEnum(_ x: borrowing AddressOnlyEnum) { switch x { case let .x(y): _ = y break case let .y(z): _ = z break } }