From 21512d1491ee3a374591f228e0260c2c92174d4c Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 2 Jul 2021 22:38:57 +0800 Subject: [PATCH] checker: fix generic fn inferring multi paras type (fix #10623) (#10626) --- vlib/v/checker/check_types.v | 4 +-- .../tests/generic_fn_infer_multi_paras_test.v | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/generic_fn_infer_multi_paras_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 622fca1954..acf11ede83 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -550,7 +550,7 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx if to_set.has_flag(.generic) { to_set = c.unwrap_generic(to_set) } - } else { + } else if param.typ.has_flag(.generic) { arg_sym := c.table.get_type_symbol(arg.typ) if arg_sym.kind == .array && param_type_sym.kind == .array { mut arg_elem_info := arg_sym.info as ast.Array @@ -588,7 +588,7 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx } } else if param.typ.has_flag(.variadic) { to_set = c.table.mktyp(arg.typ) - } else if arg_sym.kind == .struct_ && param.typ.has_flag(.generic) { + } else if arg_sym.kind == .struct_ { info := arg_sym.info as ast.Struct generic_names := info.generic_types.map(c.table.get_type_symbol(it).name) if gt_name in generic_names && info.generic_types.len == info.concrete_types.len { diff --git a/vlib/v/tests/generic_fn_infer_multi_paras_test.v b/vlib/v/tests/generic_fn_infer_multi_paras_test.v new file mode 100644 index 0000000000..9c3f5bfa74 --- /dev/null +++ b/vlib/v/tests/generic_fn_infer_multi_paras_test.v @@ -0,0 +1,36 @@ +pub struct Page { +pub mut: + lang string + page string + var_one string + var_two string +} + +fn get_keys_and_values(mut keys []string, mut values []string, mut data T) { + $for field in T.fields { + $if field.typ is string { + keys << field.name + values << data.$(field.name) + } + } +} + +fn awesome(mut data T) { + mut keys := []string{} + mut values := []string{} + get_keys_and_values(mut keys, mut values, mut data) + println(keys) + assert keys == ['lang', 'page', 'var_one', 'var_two'] + println(values) + assert values == ['vlang', 'one', 'variable one', 'variable two'] +} + +fn test_generic_fn_infer_multi_paras() { + mut page := Page{ + lang: 'vlang' + page: 'one' + var_one: 'variable one' + var_two: 'variable two' + } + awesome(mut page) +}