// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types %s | %FileCheck %s func readwrite(_ : inout String) {} struct SimpleModify { var stored: String var modifiable: String { get {} // CHECK-LABEL: sil hidden [ossa] @$s15modify_accessor12SimpleModifyV10modifiableSSvM // CHECK-SAME: : $@yield_once @convention(method) (@inout SimpleModify) -> @yields @inout String { // CHECK: [[SELF:%.*]] = begin_access [modify] [unknown] %0 : $*SimpleModify // CHECK-NEXT: [[FIELD:%.*]] = struct_element_addr [[SELF]] : $*SimpleModify, #SimpleModify.stored // CHECK-NEXT: yield [[FIELD]] : $*String, resume bb1, unwind bb2 // CHECK: bb1: // CHECK-NEXT: end_access [[SELF]] : $*SimpleModify // CHECK-NEXT: [[RET:%.*]] = tuple () // CHECK-NEXT: return [[RET]] : $() // CHECK: bb2: // CHECK-NEXT: end_access [[SELF]] : $*SimpleModify // CHECK-NEXT: unwind _modify { yield &stored } } // CHECK-LABEL: sil hidden [ossa] @$s15modify_accessor12SimpleModifyV3set6stringySS_tF // CHECK: [[VALUE:%.*]] = copy_value %0 : $String // CHECK-NEXT: [[SELF:%.*]] = begin_access [modify] [unknown] %1 : $*SimpleModify // CHECK-NEXT: // function_ref // CHECK-NEXT: [[MODIFYFN:%.*]] = function_ref @$s15modify_accessor12SimpleModifyV10modifiableSSvM // CHECK-NEXT: ([[FIELD:%.*]], [[TOKEN:%.*]]) = begin_apply [[MODIFYFN]]([[SELF]]) // CHECK-NEXT: assign [[VALUE]] to [[FIELD]] : $*String // CHECK-NEXT: end_apply [[TOKEN]] // CHECK-NEXT: end_access [[SELF]] : $*SimpleModify // CHECK-NEXT: [[RET:%.*]] = tuple () // CHECK-NEXT: return [[RET]] : $() mutating func set(string: String) { modifiable = string } // CHECK-LABEL: sil hidden [ossa] @$s15modify_accessor12SimpleModifyV0A0yyF // CHECK: [[SELF:%.*]] = begin_access [modify] [unknown] %0 : $*SimpleModify // CHECK-NEXT: // function_ref // CHECK-NEXT: [[MODIFYFN:%.*]] = function_ref @$s15modify_accessor12SimpleModifyV10modifiableSSvM // CHECK-NEXT: ([[FIELD:%.*]], [[TOKEN:%.*]]) = begin_apply [[MODIFYFN]]([[SELF]]) // CHECK-NEXT: // function_ref // CHECK-NEXT: [[READWRITE:%.*]] = function_ref @$s15modify_accessor9readwriteyySSzF // CHECK-NEXT: apply [[READWRITE]]([[FIELD]]) // CHECK-NEXT: end_apply [[TOKEN]] // CHECK-NEXT: end_access [[SELF]] : $*SimpleModify // CHECK-NEXT: [[RET:%.*]] = tuple () // CHECK-NEXT: return [[RET]] : $() mutating func modify() { readwrite(&modifiable) } } class SetterSynthesisFromModify { var stored: String = "test" var modifiable: String { get { return stored } // CHECK: sil hidden [transparent] [ossa] @$s15modify_accessor25SetterSynthesisFromModifyC10modifiableSSvs // CHECK: debug_value // CHECK-NEXT: debug_value // CHECK-NEXT: [[VALUE_BORROW:%.*]] = begin_borrow %0 : $String // CHECK-NEXT: [[VALUE:%.*]] = copy_value [[VALUE_BORROW]] : $String // CHECK-NEXT: // function_ref // CHECK-NEXT: [[MODIFYFN:%.*]] = function_ref @$s15modify_accessor25SetterSynthesisFromModifyC10modifiableSSvM // CHECK-NEXT: ([[FIELD:%.*]], [[TOKEN:%.*]]) = begin_apply [[MODIFYFN]](%1) // CHECK-NEXT: assign [[VALUE]] to [[FIELD]] : $*String // CHECK-NEXT: end_apply [[TOKEN]] // CHECK-NEXT: end_borrow [[VALUE_BORROW]] // CHECK-NEXT: destroy_value %0 : $String // CHECK-NEXT: [[RET:%.*]] = tuple () // CHECK-NEXT: return [[RET]] : $() _modify { yield &stored } } } struct ModifyAndSet { var stored: String var modifiable: String { get { return stored } _modify { yield &stored } set(value) { stored = value } } // CHECK-LABEL: sil hidden [ossa] @$s15modify_accessor12ModifyAndSetV3set6stringySS_tF // CHECK: [[VALUE:%.*]] = copy_value %0 : $String // CHECK-NEXT: [[SELF:%.*]] = begin_access [modify] [unknown] %1 : $*ModifyAndSet // CHECK-NEXT: // function_ref // CHECK-NEXT: [[SETTERFN:%.*]] = function_ref @$s15modify_accessor12ModifyAndSetV10modifiableSSvs // CHECK-NEXT: apply [[SETTERFN]]([[VALUE]], [[SELF]]) // CHECK-NEXT: end_access [[SELF]] : $*ModifyAndSet // CHECK-NEXT: [[RET:%.*]] = tuple () // CHECK-NEXT: return [[RET]] : $() mutating func set(string: String) { modifiable = string } // CHECK-LABEL: sil hidden [ossa] @$s15modify_accessor12ModifyAndSetV0A0yyF // CHECK: [[SELF:%.*]] = begin_access [modify] [unknown] %0 : $*ModifyAndSet // CHECK-NEXT: // function_ref // CHECK-NEXT: [[MODIFYFN:%.*]] = function_ref @$s15modify_accessor12ModifyAndSetV10modifiableSSvM // CHECK-NEXT: ([[FIELD:%.*]], [[TOKEN:%.*]]) = begin_apply [[MODIFYFN]]([[SELF]]) // CHECK-NEXT: // function_ref // CHECK-NEXT: [[READWRITE:%.*]] = function_ref @$s15modify_accessor9readwriteyySSzF // CHECK-NEXT: apply [[READWRITE]]([[FIELD]]) // CHECK-NEXT: end_apply [[TOKEN]] // CHECK-NEXT: end_access [[SELF]] : $*ModifyAndSet // CHECK-NEXT: [[RET:%.*]] = tuple () // CHECK-NEXT: return [[RET]] : $() mutating func modify() { readwrite(&modifiable) } }