| 1 | import os |
| 2 | import rand |
| 3 | |
| 4 | const vexe = @VEXE |
| 5 | |
| 6 | struct Foo { |
| 7 | mut: |
| 8 | a int |
| 9 | } |
| 10 | |
| 11 | fn Foo.new_non_ref() Foo { |
| 12 | return Foo{} |
| 13 | } |
| 14 | |
| 15 | fn Foo.new_ref() &Foo { |
| 16 | return &Foo{} |
| 17 | } |
| 18 | |
| 19 | fn get_map_non_ref() map[int]int { |
| 20 | return { |
| 21 | 0: 0 |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | fn get_map_ref() &map[int]int { |
| 26 | return &{ |
| 27 | 0: 0 |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | fn get_array() []int { |
| 32 | return [0] |
| 33 | } |
| 34 | |
| 35 | fn test_assign_from_call_expr() { |
| 36 | shared foo1 := Foo.new_non_ref() |
| 37 | rlock foo1 { |
| 38 | assert foo1.a == 0 |
| 39 | } |
| 40 | |
| 41 | shared foo2 := Foo.new_ref() |
| 42 | rlock foo2 { |
| 43 | assert foo2.a == 0 |
| 44 | } |
| 45 | |
| 46 | shared map1 := get_map_non_ref() |
| 47 | rlock map1 { |
| 48 | assert map1[0] == 0 |
| 49 | } |
| 50 | |
| 51 | shared map2 := get_map_ref() |
| 52 | rlock map2 { |
| 53 | assert map2[0] == 0 |
| 54 | } |
| 55 | |
| 56 | shared arr := get_array() |
| 57 | rlock arr { |
| 58 | assert arr[0] == 0 |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | fn get_int_array(arr [3]int) []int { |
| 63 | return [arr[0], arr[1], arr[2]] |
| 64 | } |
| 65 | |
| 66 | fn get_foo_array(arr [3]Foo) []Foo { |
| 67 | return [arr[0], arr[1], arr[2]] |
| 68 | } |
| 69 | |
| 70 | fn test_assign_from_call_expr_with_fixed_array() { |
| 71 | shared arr_int := get_int_array([1, 2, 3]!) |
| 72 | lock arr_int { |
| 73 | assert arr_int == [1, 2, 3] |
| 74 | } |
| 75 | |
| 76 | shared arr_foo := get_foo_array([Foo.new_non_ref(), Foo.new_non_ref(), |
| 77 | Foo.new_non_ref()]!) |
| 78 | lock arr_foo { |
| 79 | assert arr_foo == [Foo.new_non_ref(), Foo.new_non_ref(), |
| 80 | Foo.new_non_ref()] |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | fn test_re_assign_array() { |
| 85 | shared arr := [1, 2, 3] |
| 86 | lock arr { |
| 87 | arr[0] = 0 |
| 88 | assert arr == [0, 2, 3] |
| 89 | arr = [0, 0, 0] |
| 90 | assert arr == [0, 0, 0] |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | fn test_re_assign_struct() { |
| 95 | shared st := Foo{} |
| 96 | lock st { |
| 97 | st.a = 1 |
| 98 | assert st.a == 1 |
| 99 | st = Foo{2} |
| 100 | assert st.a == 2 |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | fn test_re_assign_map() { |
| 105 | shared m := map[int]int{} |
| 106 | lock m { |
| 107 | m[0] = 0 |
| 108 | assert m[0] == 0 |
| 109 | m = { |
| 110 | 0: 1 |
| 111 | } |
| 112 | assert m[0] == 1 |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | struct SharedAssignStructA { |
| 117 | commands []string |
| 118 | } |
| 119 | |
| 120 | struct SharedAssignStructB { |
| 121 | s SharedAssignStructA |
| 122 | } |
| 123 | |
| 124 | fn test_assign_from_pointer_ident_with_nested_struct() { |
| 125 | mut src := &SharedAssignStructB{} |
| 126 | shared shared_copy := src |
| 127 | shared spread_copy := SharedAssignStructB{ |
| 128 | ...src |
| 129 | } |
| 130 | rlock shared_copy, spread_copy { |
| 131 | assert shared_copy.s.commands == []string{} |
| 132 | assert spread_copy.s.commands == []string{} |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | fn test_assign_from_pointer_ident_emits_shared_copy_in_c_output() { |
| 137 | tmp_dir := os.join_path(os.vtmp_dir(), 'shared_assign_cgen_${rand.ulid()}') |
| 138 | os.mkdir_all(tmp_dir) or { panic(err) } |
| 139 | defer { |
| 140 | os.rmdir_all(tmp_dir) or {} |
| 141 | } |
| 142 | source_path := os.join_path(tmp_dir, 'main.v') |
| 143 | c_path := os.join_path(tmp_dir, 'main.c') |
| 144 | source := [ |
| 145 | 'module main', |
| 146 | '', |
| 147 | 'struct StructA {', |
| 148 | '\tcommands []string', |
| 149 | '}', |
| 150 | '', |
| 151 | 'struct StructB {', |
| 152 | '\ts StructA', |
| 153 | '}', |
| 154 | '', |
| 155 | 'fn main() {', |
| 156 | '\tmut src := &StructB{}', |
| 157 | '\tshared copy := src', |
| 158 | '\trlock copy {', |
| 159 | '\t\tprintln(copy.s)', |
| 160 | '\t}', |
| 161 | '}', |
| 162 | ].join_lines() |
| 163 | os.write_file(source_path, source) or { panic(err) } |
| 164 | res := |
| 165 | os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(c_path)} ${os.quoted_path(source_path)}') |
| 166 | assert res.exit_code == 0, res.output |
| 167 | csrc := os.read_file(c_path) or { panic(err) } |
| 168 | assert csrc.contains('__shared__main__StructB* copy = (__shared__main__StructB*)__dup__shared__main__StructB') |
| 169 | assert csrc.contains('*src}, sizeof(__shared__main__StructB))') |
| 170 | assert !csrc.contains('__shared__main__StructB* copy = src;') |
| 171 | } |
| 172 | |