From 3a0fa550b62480c8d7c2c37d9cb49b5dd8606a4d Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 17 Jul 2021 22:49:21 +0800 Subject: [PATCH] checker: fix generics fn inferring map type (fix #10835) (#10839) --- vlib/v/checker/check_types.v | 11 ++++++++ vlib/v/parser/parse_type.v | 2 +- vlib/v/tests/generic_fn_infer_map_test.v | 36 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/generic_fn_infer_map_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index e25acb92ac..1e975fe9b4 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -667,6 +667,17 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx break } } + } else if arg_sym.kind == .map && param_type_sym.kind == .map { + arg_map_info := arg_sym.info as ast.Map + param_map_info := param_type_sym.info as ast.Map + if param_map_info.key_type.has_flag(.generic) + && c.table.get_type_symbol(param_map_info.key_type).name == gt_name { + typ = arg_map_info.key_type + } + if param_map_info.value_type.has_flag(.generic) + && c.table.get_type_symbol(param_map_info.value_type).name == gt_name { + typ = arg_map_info.value_type + } } else if param.typ.has_flag(.variadic) { to_set = c.table.mktyp(arg.typ) } else if arg_sym.kind in [.struct_, .interface_, .sum_type] { diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 03f55bf8fa..6ac48f5188 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -99,7 +99,7 @@ pub fn (mut p Parser) parse_map_type() ast.Type { return 0 } key_type_supported := key_type in [ast.string_type_idx, ast.voidptr_type_idx] - || key_sym.kind == .enum_ || key_sym.kind == .placeholder + || key_sym.kind in [.enum_, .placeholder, .any] || ((key_type.is_int() || key_type.is_float() || is_alias) && !key_type.is_ptr()) if !key_type_supported { if is_alias { diff --git a/vlib/v/tests/generic_fn_infer_map_test.v b/vlib/v/tests/generic_fn_infer_map_test.v new file mode 100644 index 0000000000..33e63b524d --- /dev/null +++ b/vlib/v/tests/generic_fn_infer_map_test.v @@ -0,0 +1,36 @@ +fn print_map(x map[K]V) string { + println(x) + return '$x' +} + +fn test_generics_infer_map_type() { + m1 := map{ + 'one': 1 + } + assert print_map(m1) == "{'one': 1}" + + m2 := map{ + 'one': 1.1 + } + assert print_map(m2) == "{'one': 1.1}" + + m3 := map{ + 'one': 'a' + } + assert print_map(m3) == "{'one': 'a'}" + + m4 := map{ + 1: 'one' + } + assert print_map(m4) == "{1: 'one'}" + + m5 := map{ + 1.1: 'one' + } + assert print_map(m5) == "{1.1: 'one'}" + + m6 := map{ + 'a': 'one' + } + assert print_map(m6) == "{'a': 'one'}" +}