diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 00475ab98d416f..f4b6d46b5b15f9 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2589,6 +2589,11 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as mut needs_closing := false if arg.is_mut && !exp_is_ptr { g.write('&/*mut*/') + } else if arg.is_mut && arg_typ.is_ptr() && expected_type.is_ptr() + && g.table.sym(arg_typ).kind == .struct_ && expected_type == arg_typ.ref() { + g.write('&/*mut*/') + g.expr(arg.expr) + return } else if exp_is_ptr && !arg_is_ptr && !(arg_sym.kind == .alias && g.table.unaliased_type(arg_typ).is_pointer() && expected_type.is_pointer()) { if arg.is_mut { diff --git a/vlib/v/tests/fn_call_mut_ref_args_test.v b/vlib/v/tests/fn_call_mut_ref_args_test.v new file mode 100644 index 00000000000000..a2dd676bb4ed16 --- /dev/null +++ b/vlib/v/tests/fn_call_mut_ref_args_test.v @@ -0,0 +1,23 @@ +@[heap] +struct Client { +mut: + next &Client = unsafe { nil } + prev &Client = unsafe { nil } +} + +fn init_vm1(mut head &Client) { + for c := head; c; c = c.next { + } +} + +fn init_vm2(mut head &Client) { + for c := head; c == unsafe { nil }; c = c.next { + } +} + +fn test_fn_call_mut_ref_args() { + mut head := &Client{} + init_vm1(mut head) + init_vm2(mut head) + assert true +} diff --git a/vlib/v/tests/in_expression_test.v b/vlib/v/tests/in_expression_test.v index 70fc2e99fb2bf8..19f321931c7e7b 100644 --- a/vlib/v/tests/in_expression_test.v +++ b/vlib/v/tests/in_expression_test.v @@ -337,6 +337,6 @@ fn in_both_mut_ref(mut arr []&Bar, mut bar &Bar) { fn test_in_both_mut_and_ref() { mut arr := []&Bar{} - mut bar := Bar{} - in_both_mut_ref(mut &arr, mut &bar) + mut bar := &Bar{} + in_both_mut_ref(mut &arr, mut bar) }