From a0a33f7ff10866a82b90fe5c23ec9d7f790628da Mon Sep 17 00:00:00 2001 From: Ruofan XU <47302112+SleepyRoy@users.noreply.github.com> Date: Tue, 2 Feb 2021 10:58:32 +0800 Subject: [PATCH] checker: fix map of function as argument and direct call of function in map (#8494) --- vlib/v/checker/check_types.v | 4 ++-- vlib/v/checker/checker.v | 6 ++++++ vlib/v/tests/map_and_array_with_fns_test.v | 19 +++++++++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 977fee4560..29bc7d2787 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -85,8 +85,8 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool { // fn == 0 return true } - // array fn - if got_type_sym.kind == .array && exp_type_sym.kind == .array { + // array/map fn + if got_type_sym.kind in [.array, .map] && exp_type_sym.kind == got_type_sym.kind { if c.table.type_to_str(got) == c.table.type_to_str(expected).trim('&') { return true } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 0ad7448506..edc49f7550 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1707,6 +1707,12 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { if elem_typ.info is table.FnType { return elem_typ.info.func.return_type } + } else if sym.kind == .map { + info := sym.info as table.Map + value_typ := c.table.get_type_symbol(info.value_type) + if value_typ.info is table.FnType { + return value_typ.info.func.return_type + } } else if sym.kind == .array_fixed { info := sym.info as table.ArrayFixed elem_typ := c.table.get_type_symbol(info.elem_type) diff --git a/vlib/v/tests/map_and_array_with_fns_test.v b/vlib/v/tests/map_and_array_with_fns_test.v index a7841f19a5..7e1cc4f5a0 100644 --- a/vlib/v/tests/map_and_array_with_fns_test.v +++ b/vlib/v/tests/map_and_array_with_fns_test.v @@ -72,8 +72,7 @@ fn test_map_and_array_with_fns_typeof_and_direct_call() { assert a[0]('hello') == 15 b := {'one': foo3} assert typeof(b).name == 'map[string]fn (string) int' - // TODO: enable this - // assert b['one']('hi') == 12 + assert b['one']('hi') == 12 } fn bar1(mut a []fn (string) int) int { @@ -91,3 +90,19 @@ fn test_array_of_fns_as_argument() { a2 := [foo3] assert bar2(a2) == 15 } + +fn bar3(m map[string]fn (string) int) int { + return m['fn']('hi') +} + +fn bar4(mut m map[string]fn (string) int) int { + m['fn'] = foo4 + return m['fn']('hi') +} + +fn test_map_of_fns_as_argument() { + m1 := {'fn': foo3} + assert bar3(m1) == 12 + mut m2 := {'fn': foo3} + assert bar4(mut m2) == 22 +}