diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index f38e54d483..3f29fe51c4 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2522,11 +2522,13 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } mut ident_var_info := left.info as ast.IdentVar if ident_var_info.share == .shared_t { - if left_type.nr_muls() > 1 { - c.error('shared cannot be multi level reference', left.pos) - } left_type = left_type.set_flag(.shared_f) - left_type = left_type.set_nr_muls(1) + if is_decl { + if left_type.nr_muls() > 1 { + c.error('shared cannot be multi level reference', left.pos) + } + left_type = left_type.set_nr_muls(1) + } } if ident_var_info.share == .atomic_t { left_type = left_type.set_flag(.atomic_f) diff --git a/vlib/v/gen/array.v b/vlib/v/gen/array.v index 3fa6b862ac..aabab95571 100644 --- a/vlib/v/gen/array.v +++ b/vlib/v/gen/array.v @@ -14,17 +14,13 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { g.is_amp = false if is_amp { g.out.go_back(1) // delete the `&` already generated in `prefix_expr() - if g.is_shared { - mut shared_typ := node.typ.set_flag(.shared_f) - shared_styp = g.typ(shared_typ) - g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ') - } else { - g.write('($styp*)memdup(ADDR($styp, ') - } - } else { - if g.is_shared { - g.writeln('{.val = ($styp*)') - } + } + if g.is_shared { + mut shared_typ := node.typ.set_flag(.shared_f) + shared_styp = g.typ(shared_typ) + g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ') + } else if is_amp { + g.write('($styp*)memdup(ADDR($styp, ') } if type_sym.kind == .array_fixed { g.write('{') @@ -93,12 +89,10 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } else { g.write('0)') } - if is_amp { - if g.is_shared { - g.write('}, sizeof($shared_styp))') - } else { - g.write('), sizeof($styp))') - } + if g.is_shared { + g.write('}, sizeof($shared_styp))') + } else if is_amp { + g.write('), sizeof($styp))') } return } @@ -121,12 +115,9 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } g.write('}))') if g.is_shared { - g.write(', .mtx = sync__new_rwmutex()}') - if is_amp { - g.write(', sizeof($shared_styp))') - } + g.write('}, sizeof($shared_styp))') } else if is_amp { - g.write(', sizeof($styp))') + g.write('), sizeof($styp))') } } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 0e47096c54..987c16447c 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2692,19 +2692,14 @@ fn (mut g Gen) expr(node ast.Expr) { g.is_amp = false if is_amp { g.out.go_back(1) // delete the `&` already generated in `prefix_expr() - if g.is_shared { - mut shared_typ := node.typ.set_flag(.shared_f) - shared_styp = g.typ(shared_typ) - g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.val = ') - } else { - styp = g.typ(node.typ) - g.write('($styp*)memdup(ADDR($styp, ') - } - } else { - if g.is_shared { - // TODO: shared objects on stack should be forbidden or auto-converted to heap - g.writeln('{.val = ($styp*)') - } + } + if g.is_shared { + mut shared_typ := node.typ.set_flag(.shared_f) + shared_styp = g.typ(shared_typ) + g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.val = ') + } else if is_amp { + styp = g.typ(node.typ) + g.write('($styp*)memdup(ADDR($styp, ') } if size > 0 { if value_typ.kind == .function { @@ -2730,10 +2725,7 @@ fn (mut g Gen) expr(node ast.Expr) { g.write('new_map_2(sizeof($key_typ_str), sizeof($value_typ_str), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)') } if g.is_shared { - g.write('}') - if is_amp { - g.write(', sizeof($shared_styp))') - } + g.write('}, sizeof($shared_styp))') } else if is_amp { g.write('), sizeof($styp))') } diff --git a/vlib/v/tests/shared_array_test.v b/vlib/v/tests/shared_array_test.v index 88a91f4cda..185c5e7c10 100644 --- a/vlib/v/tests/shared_array_test.v +++ b/vlib/v/tests/shared_array_test.v @@ -40,3 +40,26 @@ fn test_shared_array() { assert f1 == 350020 } } + +fn test_shared_init_syntax() { + shared foo := &[3, 5, 6, -12] + shared bar := [-12.5, 23.125, 6.0625, 12.5] + shared baz := &[]int{len: 5, cap: 12} + shared qux := []f64{len: 7} + lock foo { + foo[2] = 20 + } + lock bar { + bar[3] = 12.5 + } + lock baz, qux { + baz[3] = 12 + qux[6] = -17.0625 + } + rlock foo, bar, baz, qux { + assert foo[2] == 20 + assert bar[3] == 12.5 + assert baz[3] == 12 + assert qux[6] == -17.0625 + } +} diff --git a/vlib/v/tests/shared_map_test.v b/vlib/v/tests/shared_map_test.v index 191b36f33a..22cd55b0ba 100644 --- a/vlib/v/tests/shared_map_test.v +++ b/vlib/v/tests/shared_map_test.v @@ -10,7 +10,7 @@ fn incr(shared foo map[string]int, key string, mut sem sync.Semaphore) { } fn test_shared_array() { - shared foo := &{'p': 10, 'q': 0} + shared foo := {'p': 10, 'q': 0} lock foo { foo['q'] = 20 } @@ -35,3 +35,26 @@ fn test_shared_array() { assert fq == 350020 } } + +fn test_shared_init_syntax() { + shared foo := &{'p': 17, 'q': -3, 'qwertz': 10} + shared bar := {'wer': 13.75, 'cvbn': -7.25, 'asd': -0.0625} + shared baz := &map[string]int{} + shared qux := map[string]f64{} + lock foo { + foo['q'] = 20 + } + lock bar { + bar['asd'] = 12.5 + } + lock baz, qux { + baz['wer'] = 12 + qux['abc'] = -17.0625 + } + rlock foo, bar, baz, qux { + assert foo['q'] == 20 + assert bar['asd'] == 12.5 + assert baz['wer'] == 12 + assert qux['abc'] == -17.0625 + } +}