diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 26f5f7a5ed14c2..9bb20fca08e15f 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -249,6 +249,12 @@ fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, lan } } + // `fn foo(mut p &Expr); mut expr := Expr{}; foo(mut expr)` + if arg.is_mut && expected.nr_muls() > 1 && !got.is_ptr() { + got_typ_str, expected_typ_str := c.get_string_names_of(got, expected) + return error('cannot use `${got_typ_str}` as `${expected_typ_str}`') + } + exp_sym_idx := c.table.sym(expected).idx got_sym_idx := c.table.sym(got).idx diff --git a/vlib/v/checker/tests/fn_call_mut_arg_mismatch_err.out b/vlib/v/checker/tests/fn_call_mut_arg_mismatch_err.out new file mode 100644 index 00000000000000..27a1d47e0f28ca --- /dev/null +++ b/vlib/v/checker/tests/fn_call_mut_arg_mismatch_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/fn_call_mut_arg_mismatch_err.vv:15:10: error: cannot use `Expr1` as `&&Expr1` in argument 1 to `foo` + 13 | name: '123' + 14 | } + 15 | foo(mut expr) + | ~~~~ + 16 | } diff --git a/vlib/v/checker/tests/fn_call_mut_arg_mismatch_err.vv b/vlib/v/checker/tests/fn_call_mut_arg_mismatch_err.vv new file mode 100644 index 00000000000000..75d05986b6d947 --- /dev/null +++ b/vlib/v/checker/tests/fn_call_mut_arg_mismatch_err.vv @@ -0,0 +1,16 @@ +module main + +pub struct Expr1 { + name string +} + +fn foo(mut expr &Expr1) { // <---- & + println(expr.name) +} + +fn main() { + mut expr := Expr1{ + name: '123' + } + foo(mut expr) +}