|
| 1 | +// RUN: %target-swift-emit-sil -module-name test -sil-verify-all -verify -enable-experimental-move-only %s | %FileCheck %s --enable-var-scope |
| 2 | + |
| 3 | +@inline(never) func someFunction() {} |
| 4 | + |
| 5 | +@_moveOnly |
| 6 | +public struct File { |
| 7 | + var x = 0 |
| 8 | + var associatedFiles: ListOfFiles = ListOfFiles() |
| 9 | + |
| 10 | + func getRawID() -> Int { return x } |
| 11 | +} |
| 12 | + |
| 13 | +public class ListOfFiles { |
| 14 | + var next: ListOfFiles? = nil |
| 15 | + public var file: File = File() |
| 16 | + |
| 17 | +// ListOfFiles.file.read |
| 18 | +// CHECK-LABEL: sil [transparent] @$s4test11ListOfFilesC4fileAA4FileVvr : $@yield_once @convention(method) (@guaranteed ListOfFiles) -> @yields @guaranteed File { |
| 19 | +// CHECK: bb0([[SELF:%[0-9]+]] : $ListOfFiles): |
| 20 | +// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $ListOfFiles, #ListOfFiles.file |
| 21 | +// CHECK: [[ACCESS:%[0-9]+]] = begin_access [read] [dynamic] [[REF]] : $*File |
| 22 | +// CHECK: [[FILE:%[0-9]+]] = load [[ACCESS]] : $*File |
| 23 | +// CHECK: yield [[FILE]] : $File, resume bb1, unwind bb2 |
| 24 | + |
| 25 | +// CHECK: bb1: |
| 26 | +// CHECK: end_access [[ACCESS]] : $*File |
| 27 | +// CHECK-NOT: destroy |
| 28 | +// CHECK: return |
| 29 | + |
| 30 | +// CHECK: bb2: |
| 31 | +// CHECK: end_access [[ACCESS]] : $*File |
| 32 | +// CHECK-NOT: destroy |
| 33 | +// CHECK: unwind |
| 34 | +// CHECK: } // end sil function |
| 35 | + |
| 36 | + |
| 37 | + |
| 38 | +// ListOfFiles.file.setter |
| 39 | +// CHECK-LABEL: sil [transparent] @$s4test11ListOfFilesC4fileAA4FileVvs : $@convention(method) (@owned File, @guaranteed ListOfFiles) -> () { |
| 40 | +// CHECK: bb0([[NEW_VAL:%.*]] : $File, [[SELF:%.*]] : $ListOfFiles): |
| 41 | +// CHECK: [[NEW_VAL_STACK:%.*]] = alloc_stack $File, let, name "value", argno 1, implicit |
| 42 | +// CHECK: store [[NEW_VAL]] to [[NEW_VAL_STACK]] : $*File |
| 43 | +// CHECK: [[NEW_VAL_RELOADED:%.*]] = load [[NEW_VAL_STACK]] : $*File |
| 44 | +// >> destroy the element currently in the field |
| 45 | +// CHECK: [[FIELD:%.*]] = ref_element_addr [[SELF]] : $ListOfFiles, #ListOfFiles.file |
| 46 | +// CHECK: destroy_addr [[FIELD]] : $*File |
| 47 | +// >> write the new value in its place |
| 48 | +// CHECK: [[FIELD_ACCESS:%.*]] = begin_access [modify] [dynamic] [[FIELD]] : $*File |
| 49 | +// CHECK: store [[NEW_VAL_RELOADED]] to [[FIELD_ACCESS]] : $*File |
| 50 | +// >> FIXME: we should not be destroying the field here rdar://105910066 |
| 51 | +// CHECK: destroy_addr [[FIELD]] : $*File |
| 52 | +// |
| 53 | +// CHECK: end_access [[FIELD_ACCESS]] : $*File |
| 54 | +// CHECK-NOT: begin_access |
| 55 | +// CHECK: return |
| 56 | +// CHECK: } // end sil function |
| 57 | + |
| 58 | + |
| 59 | + |
| 60 | +// ListOfFiles.file.modify |
| 61 | +// CHECK: sil [transparent] @$s4test11ListOfFilesC4fileAA4FileVvM : $@yield_once @convention(method) (@guaranteed ListOfFiles) -> @yields @inout File { |
| 62 | +// CHECK: bb0([[SELF:%.*]] : $ListOfFiles): |
| 63 | +// CHECK: [[FIELD:%.*]] = ref_element_addr [[SELF]] : $ListOfFiles, #ListOfFiles.file |
| 64 | +// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[FIELD]] : $*File |
| 65 | +// CHECK: yield [[ACCESS]] : $*File, resume bb1, unwind bb2 |
| 66 | +// |
| 67 | +// CHECK: bb1: |
| 68 | +// >> FIXME: we should not be destroying the field here rdar://105910066 |
| 69 | +// CHECK: destroy_addr [[FIELD]] : $*File |
| 70 | +// |
| 71 | +// CHECK: end_access [[ACCESS]] : $*File |
| 72 | +// CHECK-NOT: begin_access |
| 73 | +// |
| 74 | +// CHECK: bb2: |
| 75 | +// >> FIXME: we should not be destroying the field here rdar://105910066 |
| 76 | +// CHECK: destroy_addr [[FIELD]] : $*File |
| 77 | +// |
| 78 | +// CHECK: end_access [[ACCESS]] : $*File |
| 79 | +// CHECK-NOT: begin_access |
| 80 | +// CHECK: unwind |
| 81 | +// CHECK: } // end sil function |
| 82 | + |
| 83 | + public var freshFile: File { |
| 84 | + someFunction() |
| 85 | + return File() |
| 86 | + } |
| 87 | + |
| 88 | + |
| 89 | +// ListOfFiles.freshFile.getter |
| 90 | +// CHECK-LABEL: sil @$s4test11ListOfFilesC9freshFileAA0F0Vvg : $@convention(method) (@guaranteed ListOfFiles) -> @owned File { |
| 91 | +// CHECK: bb0({{.*}} : $ListOfFiles): |
| 92 | +// CHECK: [[SOME_FN:%.*]] = function_ref @$s4test12someFunctionyyF : $@convention(thin) () -> () |
| 93 | +// CHECK: = apply [[SOME_FN]]() : $@convention(thin) () -> () |
| 94 | +// CHECK: [[METATYPE:%.*]] = metatype $@thin File.Type |
| 95 | +// CHECK: // function_ref File.init() |
| 96 | +// CHECK: [[INIT:%.*]] = function_ref @$s4test4FileVACycfC : $@convention(method) (@thin File.Type) -> @owned File |
| 97 | +// CHECK: [[NEW_FILE:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thin File.Type) -> @owned File |
| 98 | +// CHECK: return [[NEW_FILE]] : $File |
| 99 | +// CHECK: } // end sil function |
| 100 | + |
| 101 | + |
| 102 | +// ListOfFiles.freshFile.read |
| 103 | +// CHECK-LABEL: sil [transparent] @$s4test11ListOfFilesC9freshFileAA0F0Vvr : $@yield_once @convention(method) (@guaranteed ListOfFiles) -> @yields @guaranteed File { |
| 104 | +// CHECK: bb0([[SELF:%.*]] : $ListOfFiles): |
| 105 | +// CHECK: [[GETTER:%.*]] = function_ref @$s4test11ListOfFilesC9freshFileAA0F0Vvg : $@convention(method) (@guaranteed ListOfFiles) -> @owned File |
| 106 | +// CHECK: [[FILE:%.*]] = apply [[GETTER]]([[SELF]]) : $@convention(method) (@guaranteed ListOfFiles) -> @owned File |
| 107 | +// CHECK: yield [[FILE]] : $File, resume bb1, unwind bb2 |
| 108 | +// |
| 109 | +// CHECK: bb1: |
| 110 | +// CHECK: release_value [[FILE]] : $File |
| 111 | +// CHECK: return {{.*}} : $() |
| 112 | +// |
| 113 | +// CHECK: bb2: |
| 114 | +// CHECK: release_value [[FILE]] : $File |
| 115 | +// CHECK: unwind |
| 116 | +// CHECK: } // end sil function |
| 117 | +} |
| 118 | + |
| 119 | + |
| 120 | +// access chain going through move-only and copyable types |
| 121 | +func bounceBetweenKinds(_ l: ListOfFiles) -> ListOfFiles { |
| 122 | + return l.file.associatedFiles.file.associatedFiles |
| 123 | + |
| 124 | +// CHECK-LABEL: sil hidden @$s4test18bounceBetweenKindsyAA11ListOfFilesCADF : $@convention(thin) (@guaranteed ListOfFiles) -> @owned ListOfFiles { |
| 125 | +// CHECK: bb0([[ARG:%[0-9]+]] : $ListOfFiles): |
| 126 | +// CHECK: [[REF1:%[0-9]+]] = ref_element_addr [[ARG]] : $ListOfFiles, #ListOfFiles.file |
| 127 | +// CHECK: [[ACCESS1:%[0-9]+]] = begin_access [read] [dynamic] [[REF1]] : $*File |
| 128 | +// CHECK: [[FILE1:%[0-9]+]] = load [[ACCESS1]] : $*File |
| 129 | +// CHECK: [[ASSOC_FILES1:%[0-9]+]] = struct_extract [[FILE1]] : $File, #File.associatedFiles |
| 130 | +// CHECK: strong_retain [[ASSOC_FILES1]] : $ListOfFiles |
| 131 | +// CHECK: end_access [[ACCESS1]] : $*File |
| 132 | +// CHECK-NOT: destroy |
| 133 | +// CHECK: [[REF2:%[0-9]+]] = ref_element_addr [[ASSOC_FILES1]] : $ListOfFiles, #ListOfFiles.file |
| 134 | +// CHECK: [[ACCESS2:%[0-9]+]] = begin_access [read] [dynamic] [[REF2]] : $*File |
| 135 | +// CHECK: [[FILE2:%[0-9]+]] = load [[ACCESS2]] : $*File |
| 136 | +// CHECK: [[ASSOC_FILES2:%[0-9]+]] = struct_extract [[FILE2]] : $File, #File.associatedFiles |
| 137 | +// CHECK: strong_retain [[ASSOC_FILES2]] : $ListOfFiles |
| 138 | +// CHECK: end_access [[ACCESS2]] : $*File |
| 139 | +// CHECK-NOT: destroy |
| 140 | +// CHECK: strong_release [[ASSOC_FILES1]] |
| 141 | +// CHECK-NOT: destroy |
| 142 | +// CHECK: return [[ASSOC_FILES2]] |
| 143 | +// CHECK: } // end sil function '$s4test18bounceBetweenKindsyAA11ListOfFilesCADF' |
| 144 | +} |
| 145 | + |
| 146 | +// verify that the VTable doesn't have a 'get' for a move-only type |
| 147 | +// CHECK-LABEL: sil_vtable ListOfFiles { |
| 148 | +// CHECK: #ListOfFiles.next!getter: (ListOfFiles) -> () -> ListOfFiles? : @$s4test11ListOfFilesC4nextACSgvg // ListOfFiles.next.getter |
| 149 | +// CHECK-NOT: getter |
| 150 | +// CHECK: #ListOfFiles.file!read |
| 151 | +// CHECK-NEXT: #ListOfFiles.file!setter |
| 152 | +// CHECK-NEXT: #ListOfFiles.file!modify |
| 153 | +// CHECK-NEXT: #ListOfFiles.freshFile!read: |
| 154 | +// CHECK-NOT: getter |
| 155 | +// CHECK: } |
0 commit comments