blob: 0dd8f7cd479eb9b9895932b3bd5631e09270dbec [file] [log] [blame]
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
@propertyWrapper
struct TestWrapper<ValueType> {
var wrappedValue: ValueType
}
struct State {
@TestWrapper var values: [String] = []
}
protocol StateProtocol {
@_borrowed var someValues: [String] { get set }
}
struct State1: StateProtocol {
@TestWrapper var someValues: [String] = []
}
var state = State()
state.values = Array(repeating: "", count: 20000)
state.values[1000] = "foo"
let state1 = State1()
_ = state1.someValues
// >> Check that the subscript assignment uses the _modify coroutine
// CHECK: {{%.*}} = begin_access [modify] [dynamic] {{%.*}} : $*State
// CHECK: [[REF_VALUES_MODIFY:%.*]] = function_ref @$s26property_wrapper_coroutine5StateV6valuesSaySSGvM : $@yield_once @convention(method) (@inout State) -> @yields @inout Array<String>
// CHECK: ([[RES1:%.*]], {{%.*}}) = begin_apply [[REF_VALUES_MODIFY]]({{%.*}}) : $@yield_once @convention(method) (@inout State) -> @yields @inout Array<String>
// CHECK: [[REF_ARRAY_SUBSCRIPT:%.*]] = function_ref @$sSayxSiciM : $@yield_once @convention(method) <τ_0_0> (Int, @inout Array<τ_0_0>) -> @yields @inout τ_0_0
// CHECK: ({{%.*}}, {{%.*}}) = begin_apply [[REF_ARRAY_SUBSCRIPT]]<String>({{%.*}}, [[RES1]]) : $@yield_once @convention(method) <τ_0_0> (Int, @inout Array<τ_0_0>) -> @yields @inout τ_0_0
// >> Check that the _modify coroutine is synthesized properly
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_coroutine5StateV6valuesSaySSGvM : $@yield_once @convention(method) (@inout State) -> @yields @inout Array<String> {
// CHECK: bb0([[STATE:%.*]] : $*State):
// CHECK: debug_value_addr [[STATE]] : $*State, var, name "self", argno {{.*}}
// CHECK: [[BEGIN_ACCESS:%.*]] = begin_access [modify] [unknown] [[STATE]] : $*State
// CHECK: [[BACKING_ADDR:%.*]] = struct_element_addr [[BEGIN_ACCESS]] : $*State, #State._values
// CHECK: [[VALUE_ADDR:%.*]] = struct_element_addr [[BACKING_ADDR]] : $*TestWrapper<Array<String>>, #TestWrapper.wrappedValue
// CHECK: yield [[VALUE_ADDR]] : $*Array<String>, resume bb1, unwind bb2
//
// CHECK: bb1:
// CHECK: end_access [[BEGIN_ACCESS]] : $*State
// CHECK: [[RETURN:%.*]] = tuple ()
// CHECK: return [[RETURN]] : $()
//
// CHECK: bb2:
// CHECK: end_access [[BEGIN_ACCESS]] : $*State
// CHECK: unwind
// CHECK-END: }
// >> Check that the _read coroutine is synthesized properly
// CHECK-LABEL: sil shared [ossa] @$s26property_wrapper_coroutine6State1V10someValuesSaySSGvr : $@yield_once @convention(method) (@guaranteed State1) -> @yields @guaranteed Array<String> {
// CHECK: bb0([[STATE1:%.*]] : @guaranteed $State1):
// CHECK: debug_value [[SELF:%.*]] : $State1, let, name "self", argno {{.*}}
// CHECK: [[EXTRACT_VALUE:%.*]] = struct_extract %0 : $State1, #State1._someValues
// CHECK: [[COPY_VALUE:%.*]] = copy_value [[EXTRACT_VALUE]] : $TestWrapper<Array<String>>
// CHECK: [[BEGIN_BORROW:%.*]] = begin_borrow [[COPY_VALUE]] : $TestWrapper<Array<String>>
// CHECK: [[EXTRACT_WRAPPEDVALUE:%.*]] = struct_extract [[BEGIN_BORROW]] : $TestWrapper<Array<String>>, #TestWrapper.wrappedValue
// CHECK: yield [[EXTRACT_WRAPPEDVALUE]] : $Array<String>, resume bb1, unwind bb2
//
// CHECK: bb1:
// CHECK: end_borrow [[BEGIN_BORROW]] : $TestWrapper<Array<String>>
// CHECK: destroy_value [[COPY_VALUE]] : $TestWrapper<Array<String>>
// CHECK: [[RETURN:%.*]] = tuple ()
// CHECK: return [[RETURN]] : $()
//
// CHECK: bb2:
// CHECK: end_borrow [[BEGIN_BORROW]] : $TestWrapper<Array<String>>
// CHECK: destroy_value [[COPY_VALUE]] : $TestWrapper<Array<String>>
// CHECK: unwind
// CHECK-END: }