diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7f41800367..103beb43c8 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1826,6 +1826,19 @@ fn (mut c Checker) stmt(node ast.Stmt) { c.error('expression in `go` must be a function call', it.call_expr.position()) } c.expr(it.call_expr) + if it.call_expr is ast.CallExpr { + call_expr := it.call_expr as ast.CallExpr + + // Make sure there are no mutable arguments + for arg in call_expr.args { + if arg.is_mut && !arg.typ.is_ptr() { + c.error('function in `go` statement cannot contain mutable non-reference arguments', arg.expr.position()) + } + } + if call_expr.is_method && call_expr.receiver_type.is_ptr() && !call_expr.left_type.is_ptr() { + c.error('method in `go` statement cannot have non-reference mutable receiver', call_expr.left.position()) + } + } } // ast.HashStmt {} ast.Import {} diff --git a/vlib/v/checker/tests/go_mut_arg.out b/vlib/v/checker/tests/go_mut_arg.out new file mode 100644 index 0000000000..3544f2cd87 --- /dev/null +++ b/vlib/v/checker/tests/go_mut_arg.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/go_mut_arg.v:14:16: error: function in `go` statement cannot contain mutable non-reference arguments + 12 | a: 0 + 13 | } + 14 | go change(mut x) + | ^ + 15 | } diff --git a/vlib/v/checker/tests/go_mut_arg.vv b/vlib/v/checker/tests/go_mut_arg.vv new file mode 100644 index 0000000000..af86f15d1c --- /dev/null +++ b/vlib/v/checker/tests/go_mut_arg.vv @@ -0,0 +1,15 @@ +struct St { +mut: + a int +} + +fn change(mut a St) { + a.a++ +} + +fn main() { + mut x := St{ + a: 0 + } + go change(mut x) +} diff --git a/vlib/v/checker/tests/go_mut_receiver.out b/vlib/v/checker/tests/go_mut_receiver.out new file mode 100644 index 0000000000..5033b5d2be --- /dev/null +++ b/vlib/v/checker/tests/go_mut_receiver.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/go_mut_receiver.v:14:5: error: method in `go` statement cannot have non-reference mutable receiver + 12 | a: 0 + 13 | } + 14 | go x.change() + | ^ + 15 | } diff --git a/vlib/v/checker/tests/go_mut_receiver.vv b/vlib/v/checker/tests/go_mut_receiver.vv new file mode 100644 index 0000000000..0b64d51c23 --- /dev/null +++ b/vlib/v/checker/tests/go_mut_receiver.vv @@ -0,0 +1,15 @@ +struct St { +mut: + a int +} + +fn (mut a St) change() { + a.a++ +} + +fn main() { + mut x := St{ + a: 0 + } + go x.change() +}