From fe6658d374ba577fec0e262a571acbaf3745483b Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 9 Dec 2024 11:22:47 -0300 Subject: [PATCH] checker: allow fixed array where voidptr is expected (fix #23090) (#23100) --- vlib/v/checker/check_types.v | 3 +++ vlib/v/checker/fn.v | 27 +++++++++---------- .../tests/array_insert_type_mismatch.out | 2 +- vlib/v/checker/tests/array_insert_val_err.out | 14 ++++++++++ vlib/v/checker/tests/array_insert_val_err.vv | 8 ++++++ .../tests/array_prepend_type_mismatch.out | 2 +- vlib/v/checker/tests/fixed_array_conv.out | 7 ----- vlib/v/tests/array_insert_array_fixed_test.v | 5 ++++ .../v/tests/fns/fixed_array_on_voidptr_test.v | 11 ++++++++ 9 files changed, 56 insertions(+), 23 deletions(-) create mode 100644 vlib/v/checker/tests/array_insert_val_err.out create mode 100644 vlib/v/checker/tests/array_insert_val_err.vv create mode 100644 vlib/v/tests/array_insert_array_fixed_test.v create mode 100644 vlib/v/tests/fns/fixed_array_on_voidptr_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index c5523d501..16796e835 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -366,6 +366,9 @@ fn (mut c Checker) check_expected_call_arg(got_ ast.Type, expected_ ast.Type, la if got == ast.void_type { return error('`${arg.expr}` (no value) used as value') } + if expected == ast.voidptr_type && got_typ_sym.kind == .array_fixed { + return + } got_typ_str, expected_typ_str := c.get_string_names_of(got_, exp_type) return error('cannot use `${got_typ_str}` as `${expected_typ_str}`') } diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 13d889b0e..c567e6978 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -3372,23 +3372,22 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as } c.check_for_mut_receiver(mut node.left) info := left_sym.info as ast.Array - mut arg_expr := if method_name == 'insert' { - node.args[1].expr - } else { - node.args[0].expr - } - arg_type := c.expr(mut arg_expr) - arg_sym := c.table.sym(arg_type) - if !c.check_types(arg_type, info.elem_type) && !c.check_types(left_type, arg_type) { - c.error('cannot ${method_name} `${arg_sym.name}` to `${left_sym.name}`', arg_expr.pos()) - } - for i, mut arg in node.args { - node.args[i].typ = c.expr(mut arg.expr) - } + val_arg_n := if method_name == 'insert' { 1 } else { 0 } node.receiver_type = ast.array_type.ref() node.return_type = ast.void_type + if method := c.table.find_method(left_sym, method_name) { - for i, arg in node.args { + for i, mut arg in node.args { + node.args[i].typ = c.expr(mut arg.expr) + if i == val_arg_n { + arg_sym := c.table.sym(node.args[i].typ) + if !c.check_types(node.args[i].typ, info.elem_type) + && !c.check_types(left_type, node.args[i].typ) { + c.error('cannot ${method_name} `${arg_sym.name}` to `${left_sym.name}`', + arg.expr.pos()) + continue + } + } c.check_expected_call_arg(arg.typ, method.params[i + 1].typ, node.language, arg) or { c.error('${err.msg()} in argument ${i + 1} to `${left_sym.name}.${method_name}`', diff --git a/vlib/v/checker/tests/array_insert_type_mismatch.out b/vlib/v/checker/tests/array_insert_type_mismatch.out index 78f0a649f..25a1bf75b 100644 --- a/vlib/v/checker/tests/array_insert_type_mismatch.out +++ b/vlib/v/checker/tests/array_insert_type_mismatch.out @@ -41,7 +41,7 @@ vlib/v/checker/tests/array_insert_type_mismatch.vv:8:14: error: cannot insert `[ 9 | println(a) 10 | vlib/v/checker/tests/array_insert_type_mismatch.vv:12:14: error: cannot insert `[][][]int` to `[][]int` - 10 | + 10 | 11 | mut b := [[1, 2, 3]] 12 | b.insert(0, [[[2]]]) | ~~~~~~~ diff --git a/vlib/v/checker/tests/array_insert_val_err.out b/vlib/v/checker/tests/array_insert_val_err.out new file mode 100644 index 000000000..b17d1d50d --- /dev/null +++ b/vlib/v/checker/tests/array_insert_val_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/array_insert_val_err.vv:3:16: error: cannot insert `[]int` to `[][2]int` + 1 | fn main() { + 2 | mut arr := [][2]int{} + 3 | arr.insert(0, [1, 2]) + | ~~~~~~ + 4 | arr.insert(0, [1, 2]!) + 5 | arr.prepend([1, 2]) +vlib/v/checker/tests/array_insert_val_err.vv:5:14: error: cannot prepend `[]int` to `[][2]int` + 3 | arr.insert(0, [1, 2]) + 4 | arr.insert(0, [1, 2]!) + 5 | arr.prepend([1, 2]) + | ~~~~~~ + 6 | arr.prepend([1, 2]!) + 7 | println(arr) diff --git a/vlib/v/checker/tests/array_insert_val_err.vv b/vlib/v/checker/tests/array_insert_val_err.vv new file mode 100644 index 000000000..05799b898 --- /dev/null +++ b/vlib/v/checker/tests/array_insert_val_err.vv @@ -0,0 +1,8 @@ +fn main() { + mut arr := [][2]int{} + arr.insert(0, [1, 2]) + arr.insert(0, [1, 2]!) + arr.prepend([1, 2]) + arr.prepend([1, 2]!) + println(arr) +} diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch.out b/vlib/v/checker/tests/array_prepend_type_mismatch.out index 8e74b7f08..85effa0b3 100644 --- a/vlib/v/checker/tests/array_prepend_type_mismatch.out +++ b/vlib/v/checker/tests/array_prepend_type_mismatch.out @@ -41,7 +41,7 @@ vlib/v/checker/tests/array_prepend_type_mismatch.vv:8:12: error: cannot prepend 9 | println(a) 10 | vlib/v/checker/tests/array_prepend_type_mismatch.vv:12:12: error: cannot prepend `[][][]int` to `[][]int` - 10 | + 10 | 11 | mut b := [[1, 2, 3]] 12 | b.prepend([[[2]]]) | ~~~~~~~ diff --git a/vlib/v/checker/tests/fixed_array_conv.out b/vlib/v/checker/tests/fixed_array_conv.out index bf6a171fe..4f54b0c8a 100644 --- a/vlib/v/checker/tests/fixed_array_conv.out +++ b/vlib/v/checker/tests/fixed_array_conv.out @@ -33,13 +33,6 @@ vlib/v/checker/tests/fixed_array_conv.vv:5:6: error: cannot assign to `ip`: expe | ~~~ 6 | _ = &int(arr) 7 | _ = p -vlib/v/checker/tests/fixed_array_conv.vv:11:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup` - 9 | - 10 | unsafe { - 11 | _ = memdup(arr, 1) - | ~~~ - 12 | _ = tos(arr, 1) - 13 | fn (p &int) {}(arr) vlib/v/checker/tests/fixed_array_conv.vv:12:10: error: cannot use `[2]int` as `&u8` in argument 1 to `tos` 10 | unsafe { 11 | _ = memdup(arr, 1) diff --git a/vlib/v/tests/array_insert_array_fixed_test.v b/vlib/v/tests/array_insert_array_fixed_test.v new file mode 100644 index 000000000..f9d98f70b --- /dev/null +++ b/vlib/v/tests/array_insert_array_fixed_test.v @@ -0,0 +1,5 @@ +fn test_main() { + mut arr := [][2]int{} + arr.insert(0, [1, 2]!) + assert arr == [[1, 2]!] +} diff --git a/vlib/v/tests/fns/fixed_array_on_voidptr_test.v b/vlib/v/tests/fns/fixed_array_on_voidptr_test.v new file mode 100644 index 000000000..21d49d5c3 --- /dev/null +++ b/vlib/v/tests/fns/fixed_array_on_voidptr_test.v @@ -0,0 +1,11 @@ +fn test_main() { + mut b := [2]int{} + b[0] = 1 + b[1] = 2 + mut a := unsafe { memdup(b, 8) } + x := &int(a) + unsafe { + assert x[0] == 1 + assert x[1] == 2 + } +} -- 2.39.5