checker: fix call with mut arg with different pointer levels (fix #23157) (#23428)

This commit is contained in:
Felipe Pena 2025-01-11 14:25:49 -03:00 committed by GitHub
parent bed28d1e8b
commit 1c2f1a3504
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 51 additions and 6 deletions

View File

@ -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)` // `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_) got_typ_str, expected_typ_str := c.get_string_names_of(got_, expected_)
return error('cannot use `${got_typ_str}` as `${expected_typ_str}`') return error('cannot use `${got_typ_str}` as `${expected_typ_str}`')
} }

View File

@ -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 |

View File

@ -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)
}

View File

@ -338,5 +338,5 @@ fn in_both_mut_ref(mut arr []&Bar, mut bar &Bar) {
fn test_in_both_mut_and_ref() { fn test_in_both_mut_and_ref() {
mut arr := []&Bar{} mut arr := []&Bar{}
mut bar := &Bar{} mut bar := &Bar{}
in_both_mut_ref(mut &arr, mut bar) in_both_mut_ref(mut &arr, mut &bar)
} }

View File

@ -17,7 +17,7 @@ fn init_vm2(mut head &Client) {
fn test_fn_call_mut_ref_args() { fn test_fn_call_mut_ref_args() {
mut head := &Client{} mut head := &Client{}
init_vm1(mut head) init_vm1(mut &head)
init_vm2(mut head) init_vm2(mut &head)
assert true assert true
} }

View File

@ -9,7 +9,7 @@ pub type Expr = Expr1 | Expr2
pub struct Gen { pub struct Gen {
} }
fn (mut g Gen) foo(mut expr &Expr1) string { fn (mut g Gen) foo(mut expr Expr1) string {
return '${expr}' return '${expr}'
} }

View File

@ -23,6 +23,6 @@ fn bang(mut logr ?&Logger, this string) {
fn test_option_reference_params() { fn test_option_reference_params() {
mut logr := new_logger() mut logr := new_logger()
bang(mut logr, 'bang!') bang(mut &logr, 'bang!')
assert true assert true
} }