From 1f3336c9d34278ccf7c8e579e792377139ce6121 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 22 May 2022 21:28:53 +0800 Subject: [PATCH] checker: fix map get anon fn value with mut argument (fix #14479) (#14493) --- vlib/v/checker/fn.v | 16 +++++++--------- vlib/v/checker/tests/fn_type_mismatch.out | 15 ++++++++++++++- .../map_get_anon_fn_value_with_mut_arg_test.v | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 vlib/v/tests/map_get_anon_fn_value_with_mut_arg_test.v diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 7d58add0ca..78227bda70 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -559,12 +559,12 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) } if !found && mut node.left is ast.IndexExpr { c.expr(node.left) - sym := c.table.sym(node.left.left_type) + sym := c.table.final_sym(node.left.left_type) if sym.info is ast.Array { elem_sym := c.table.sym(sym.info.elem_type) if elem_sym.info is ast.FnType { - node.return_type = elem_sym.info.func.return_type - return elem_sym.info.func.return_type + func = elem_sym.info.func + found = true } else { c.error('cannot call the element of the array, it is not a function', node.pos) @@ -572,23 +572,21 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) } else if sym.info is ast.Map { value_sym := c.table.sym(sym.info.value_type) if value_sym.info is ast.FnType { - node.return_type = value_sym.info.func.return_type - return value_sym.info.func.return_type + func = value_sym.info.func + found = true } else { c.error('cannot call the value of the map, it is not a function', node.pos) } } else if sym.info is ast.ArrayFixed { elem_sym := c.table.sym(sym.info.elem_type) if elem_sym.info is ast.FnType { - node.return_type = elem_sym.info.func.return_type - return elem_sym.info.func.return_type + func = elem_sym.info.func + found = true } else { c.error('cannot call the element of the array, it is not a function', node.pos) } } - found = true - return ast.string_type } if !found && mut node.left is ast.CallExpr { c.expr(node.left) diff --git a/vlib/v/checker/tests/fn_type_mismatch.out b/vlib/v/checker/tests/fn_type_mismatch.out index 1fe81fe20c..922c19abcf 100644 --- a/vlib/v/checker/tests/fn_type_mismatch.out +++ b/vlib/v/checker/tests/fn_type_mismatch.out @@ -1,7 +1,20 @@ vlib/v/checker/tests/fn_type_mismatch.vv:11:15: error: invalid array element: expected `fn (int, int) f32`, not `fn (f32, f32) f32` - 9 | + 9 | 10 | fn main() { 11 | fns := [add, div] | ~~~ 12 | println(fns[0](10.0, 5.0)) 13 | println(fns[1](10.0, 5.0)) +vlib/v/checker/tests/fn_type_mismatch.vv:12:17: error: cannot use `float literal` as `int` in argument 1 to `` + 10 | fn main() { + 11 | fns := [add, div] + 12 | println(fns[0](10.0, 5.0)) + | ~~~~ + 13 | println(fns[1](10.0, 5.0)) + 14 | } +vlib/v/checker/tests/fn_type_mismatch.vv:13:17: error: cannot use `float literal` as `int` in argument 1 to `` + 11 | fns := [add, div] + 12 | println(fns[0](10.0, 5.0)) + 13 | println(fns[1](10.0, 5.0)) + | ~~~~ + 14 | } diff --git a/vlib/v/tests/map_get_anon_fn_value_with_mut_arg_test.v b/vlib/v/tests/map_get_anon_fn_value_with_mut_arg_test.v new file mode 100644 index 0000000000..7e2af8b2c6 --- /dev/null +++ b/vlib/v/tests/map_get_anon_fn_value_with_mut_arg_test.v @@ -0,0 +1,15 @@ +struct Bar {} + +fn test_map_get_anon_fn_value_with_mut_arg() { + foo := { + 0: fn (mut bar Bar) int { + return 22 + } + } + + mut bar := Bar{} + ret := foo[0](mut bar) + + println(ret) + assert ret == 22 +}