From 1c2f1a35040752af8aea8daf8226bd231d3bca19 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 11 Jan 2025 14:25:49 -0300 Subject: [PATCH] checker: fix call with mut arg with different pointer levels (fix #23157) (#23428) --- vlib/v/checker/check_types.v | 2 +- .../tests/mut_arg_different_muls_err.out | 7 ++++ .../tests/mut_arg_different_muls_err.vv | 38 +++++++++++++++++++ .../tests/conditions/ifs/in_expression_test.v | 2 +- vlib/v/tests/fns/fn_call_mut_ref_args_test.v | 4 +- .../fns/fn_mut_arg_of_sumtype_ref_test.v | 2 +- .../options/option_reference_params_test.v | 2 +- 7 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 vlib/v/checker/tests/mut_arg_different_muls_err.out create mode 100644 vlib/v/checker/tests/mut_arg_different_muls_err.vv diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 1f090c3a58..6396ecff7c 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -267,7 +267,7 @@ fn (mut c Checker) check_expected_call_arg(got_ ast.Type, expected_ ast.Type, la } // `fn foo(mut p &Expr); mut expr := Expr{}; foo(mut expr)` - if arg.is_mut && expected.nr_muls() > 1 && !got.is_ptr() { + if arg.is_mut && expected.nr_muls() > 1 && got.nr_muls() < expected.nr_muls() { got_typ_str, expected_typ_str := c.get_string_names_of(got_, expected_) return error('cannot use `${got_typ_str}` as `${expected_typ_str}`') } diff --git a/vlib/v/checker/tests/mut_arg_different_muls_err.out b/vlib/v/checker/tests/mut_arg_different_muls_err.out new file mode 100644 index 0000000000..917be05b15 --- /dev/null +++ b/vlib/v/checker/tests/mut_arg_different_muls_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/mut_arg_different_muls_err.vv:26:21: error: cannot use `&Window` as `&&Window` in argument 1 to `window_resized` + 24 | + 25 | fn on_event(mut w Window) { + 26 | window_resized(mut w) + | ^ + 27 | } + 28 | diff --git a/vlib/v/checker/tests/mut_arg_different_muls_err.vv b/vlib/v/checker/tests/mut_arg_different_muls_err.vv new file mode 100644 index 0000000000..b4af7c3030 --- /dev/null +++ b/vlib/v/checker/tests/mut_arg_different_muls_err.vv @@ -0,0 +1,38 @@ +pub type WindowResizeFn = fn (window &Window, w int, h int) + +@[heap] +pub struct Window { + id string = '_window_' +pub mut: + resize_fn WindowResizeFn = unsafe { nil } +} + +@[params] +pub struct WindowParams { +pub: + on_resize WindowResizeFn = unsafe { nil } +} + +fn window_resized(mut w &Window) { + window_width, window_height := 200, 100 + + if w.resize_fn != WindowResizeFn(0) { + println('fn present ${window_width} ${window_height}') + w.resize_fn(w, window_width, window_height) + } +} + +fn on_event(mut w Window) { + window_resized(mut w) +} + +fn on_resize(window &Window, w int, h int) { + println(' ${w} ${h}') +} + +fn main() { + mut w := &Window{ + resize_fn: on_resize + } + on_event(mut w) +} diff --git a/vlib/v/tests/conditions/ifs/in_expression_test.v b/vlib/v/tests/conditions/ifs/in_expression_test.v index 19f321931c..dfbe65d29a 100644 --- a/vlib/v/tests/conditions/ifs/in_expression_test.v +++ b/vlib/v/tests/conditions/ifs/in_expression_test.v @@ -338,5 +338,5 @@ 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) + in_both_mut_ref(mut &arr, mut &bar) } diff --git a/vlib/v/tests/fns/fn_call_mut_ref_args_test.v b/vlib/v/tests/fns/fn_call_mut_ref_args_test.v index a2dd676bb4..f90100f1f6 100644 --- a/vlib/v/tests/fns/fn_call_mut_ref_args_test.v +++ b/vlib/v/tests/fns/fn_call_mut_ref_args_test.v @@ -17,7 +17,7 @@ fn init_vm2(mut head &Client) { fn test_fn_call_mut_ref_args() { mut head := &Client{} - init_vm1(mut head) - init_vm2(mut head) + init_vm1(mut &head) + init_vm2(mut &head) assert true } diff --git a/vlib/v/tests/fns/fn_mut_arg_of_sumtype_ref_test.v b/vlib/v/tests/fns/fn_mut_arg_of_sumtype_ref_test.v index 07980ebc5e..948dc799f4 100644 --- a/vlib/v/tests/fns/fn_mut_arg_of_sumtype_ref_test.v +++ b/vlib/v/tests/fns/fn_mut_arg_of_sumtype_ref_test.v @@ -9,7 +9,7 @@ pub type Expr = Expr1 | Expr2 pub struct Gen { } -fn (mut g Gen) foo(mut expr &Expr1) string { +fn (mut g Gen) foo(mut expr Expr1) string { return '${expr}' } diff --git a/vlib/v/tests/options/option_reference_params_test.v b/vlib/v/tests/options/option_reference_params_test.v index ba3f4c06f2..f1d2e3decb 100644 --- a/vlib/v/tests/options/option_reference_params_test.v +++ b/vlib/v/tests/options/option_reference_params_test.v @@ -23,6 +23,6 @@ fn bang(mut logr ?&Logger, this string) { fn test_option_reference_params() { mut logr := new_logger() - bang(mut logr, 'bang!') + bang(mut &logr, 'bang!') assert true }