diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index bf1e2421c0f3d9..3771bcb0e5898e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3192,7 +3192,11 @@ fn (mut g Gen) expr(node_ ast.Expr) { mut shared_styp := '' if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block { ret_sym := g.table.sym(ret_type) - shared_typ := ret_type.set_flag(.shared_f) + shared_typ := if ret_type.is_ptr() { + ret_type.deref().set_flag(.shared_f) + } else { + ret_type.set_flag(.shared_f) + } shared_styp = g.typ(shared_typ) if ret_sym.kind == .array { g.writeln('(${shared_styp}*)__dup_shared_array(&(${shared_styp}){.mtx = {0}, .val =') @@ -3208,6 +3212,10 @@ fn (mut g Gen) expr(node_ ast.Expr) { 0 } + if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block + && ret_type.is_ptr() { + g.write('*'.repeat(ret_type.nr_muls())) + } g.call_expr(node) if g.is_autofree && !g.is_builtin_mod && !g.is_js_call && g.strs_to_free0.len == 0 && !g.inside_lambda { diff --git a/vlib/v/tests/shared_assign_test.v b/vlib/v/tests/shared_assign_test.v new file mode 100644 index 00000000000000..51f847633661d4 --- /dev/null +++ b/vlib/v/tests/shared_assign_test.v @@ -0,0 +1,87 @@ +struct Foo { +mut: + a int +} + +fn Foo.new_non_ref() Foo { + return Foo{} +} + +fn Foo.new_ref() &Foo { + return &Foo{} +} + +fn get_map_non_ref() map[int]int { + return { + 0: 0 + } +} + +fn get_map_ref() &map[int]int { + return &{ + 0: 0 + } +} + +fn get_array() []int { + return [0] +} + +fn test_assign_from_call_expr() { + shared foo1 := Foo.new_non_ref() + rlock foo1 { + assert foo1.a == 0 + } + + shared foo2 := Foo.new_ref() + rlock foo2 { + assert foo2.a == 0 + } + + shared map1 := get_map_non_ref() + rlock map1 { + assert map1[0] == 0 + } + + shared map2 := get_map_ref() + rlock map2 { + assert map2[0] == 0 + } + + shared arr := get_array() + rlock arr { + assert arr[0] == 0 + } +} + +fn test_re_assign_array() { + shared arr := [1, 2, 3] + lock arr { + arr[0] = 0 + assert arr == [0, 2, 3] + arr = [0, 0, 0] + assert arr == [0, 0, 0] + } +} + +fn test_re_assign_struct() { + shared st := Foo{} + lock st { + st.a = 1 + assert st.a == 1 + st = Foo{2} + assert st.a == 2 + } +} + +fn test_re_assign_map() { + shared m := map[int]int{} + lock m { + m[0] = 0 + assert m[0] == 0 + m = { + 0: 1 + } + assert m[0] == 1 + } +} diff --git a/vlib/v/tests/shared_re_assign_test.v b/vlib/v/tests/shared_re_assign_test.v deleted file mode 100644 index 427490e28808ac..00000000000000 --- a/vlib/v/tests/shared_re_assign_test.v +++ /dev/null @@ -1,36 +0,0 @@ -fn test_re_assign_array() { - shared arr := [1, 2, 3] - lock arr { - arr[0] = 0 - assert arr == [0, 2, 3] - arr = [0, 0, 0] - assert arr == [0, 0, 0] - } -} - -struct Foo { -mut: - a int -} - -fn test_re_assign_struct() { - shared st := Foo{} - lock st { - st.a = 1 - assert st.a == 1 - st = Foo{2} - assert st.a == 2 - } -} - -fn test_re_assign_map() { - shared m := map[int]int{} - lock m { - m[0] = 0 - assert m[0] == 0 - m = { - 0: 1 - } - assert m[0] == 1 - } -}