From fb528cd0365412e4eb9a5f3cb65d484d9b19a0fa Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 30 Dec 2024 23:11:51 +0800 Subject: [PATCH] checker: check shared variables types (fix #23313, fix #23314) (#23316) --- vlib/v/checker/assign.v | 4 ++++ .../tests/globals/assign_global_to_shared_err.out | 6 ++++++ .../tests/globals/assign_global_to_shared_err.vv | 2 +- vlib/v/checker/tests/shared_variables_type_err.out | 7 +++++++ vlib/v/checker/tests/shared_variables_type_err.vv | 14 ++++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 vlib/v/checker/tests/shared_variables_type_err.out create mode 100644 vlib/v/checker/tests/shared_variables_type_err.vv diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 23aaf67e4d6b43..2f897013ab8030 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -217,6 +217,10 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { } else if right is ast.ComptimeSelector { right_type = c.comptime.comptime_for_field_type } + if is_decl && left is ast.Ident && left.info is ast.IdentVar + && (left.info as ast.IdentVar).share == .shared_t && c.table.sym(right_type).kind !in [.array, .map, .struct] { + c.fatal('shared variables must be structs, arrays or maps', right.pos()) + } if is_decl || is_shared_re_assign { // check generic struct init and return unwrap generic struct type if mut right is ast.StructInit { diff --git a/vlib/v/checker/tests/globals/assign_global_to_shared_err.out b/vlib/v/checker/tests/globals/assign_global_to_shared_err.out index 8d4a0839ca602a..46b7c6340a5616 100644 --- a/vlib/v/checker/tests/globals/assign_global_to_shared_err.out +++ b/vlib/v/checker/tests/globals/assign_global_to_shared_err.out @@ -10,3 +10,9 @@ vlib/v/checker/tests/globals/assign_global_to_shared_err.vv:5:14: error: cannot 5 | shared b := a | ^ 6 | } +vlib/v/checker/tests/globals/assign_global_to_shared_err.vv:5:14: error: cannot copy map: call `move` or `clone` method (or use a reference) + 3 | + 4 | fn main() { + 5 | shared b := a + | ^ + 6 | } diff --git a/vlib/v/checker/tests/globals/assign_global_to_shared_err.vv b/vlib/v/checker/tests/globals/assign_global_to_shared_err.vv index b0e23e93d3335f..cab98f2f5ce2b7 100644 --- a/vlib/v/checker/tests/globals/assign_global_to_shared_err.vv +++ b/vlib/v/checker/tests/globals/assign_global_to_shared_err.vv @@ -1,5 +1,5 @@ @[has_globals] -__global a = 0 +__global a = {1: 'one', 2: 'two'} fn main() { shared b := a diff --git a/vlib/v/checker/tests/shared_variables_type_err.out b/vlib/v/checker/tests/shared_variables_type_err.out new file mode 100644 index 00000000000000..70ba599947d0c7 --- /dev/null +++ b/vlib/v/checker/tests/shared_variables_type_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/shared_variables_type_err.vv:7:16: error: shared variables must be structs, arrays or maps + 5 | + 6 | fn main() { + 7 | shared foo := Foo.one + | ~~~~~~~ + 8 | rlock foo { + 9 | match foo { diff --git a/vlib/v/checker/tests/shared_variables_type_err.vv b/vlib/v/checker/tests/shared_variables_type_err.vv new file mode 100644 index 00000000000000..87ca2f66382320 --- /dev/null +++ b/vlib/v/checker/tests/shared_variables_type_err.vv @@ -0,0 +1,14 @@ +enum Foo { + zero + one +} + +fn main() { + shared foo := Foo.one + rlock foo { + match foo { + .zero { println('0000') } + .one { println('1111') } + } + } +}