From 13ddfaa433fdfd4bb2790fc3aced74c33015ac19 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 30 May 2021 19:06:52 +0800 Subject: [PATCH] checker: fix generic fn infer nested struct (#10262) --- vlib/v/checker/check_types.v | 18 ++++++++++++----- .../generic_fn_infer_nested_struct_test.v | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 vlib/v/tests/generic_fn_infer_nested_struct_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 27cb5fcbaf..af258a925b 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -506,11 +506,19 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx sym := c.table.get_type_symbol(call_expr.receiver_type) if sym.kind == .struct_ { info := sym.info as ast.Struct - receiver_generic_names := info.generic_types.map(c.table.get_type_symbol(it).name) - if gt_name in receiver_generic_names - && info.generic_types.len == info.concrete_types.len { - idx := receiver_generic_names.index(gt_name) - typ = info.concrete_types[idx] + if c.table.cur_fn.generic_names.len > 0 { // in generic fn + if gt_name in c.table.cur_fn.generic_names + && c.table.cur_fn.generic_names.len == c.cur_concrete_types.len { + idx := c.table.cur_fn.generic_names.index(gt_name) + typ = c.cur_concrete_types[idx] + } + } else { // in non-generic fn + receiver_generic_names := info.generic_types.map(c.table.get_type_symbol(it).name) + if gt_name in receiver_generic_names + && info.generic_types.len == info.concrete_types.len { + idx := receiver_generic_names.index(gt_name) + typ = info.concrete_types[idx] + } } } } diff --git a/vlib/v/tests/generic_fn_infer_nested_struct_test.v b/vlib/v/tests/generic_fn_infer_nested_struct_test.v new file mode 100644 index 0000000000..19de4a4227 --- /dev/null +++ b/vlib/v/tests/generic_fn_infer_nested_struct_test.v @@ -0,0 +1,20 @@ +struct Item { + value T +} + +fn (i Item) unwrap() T { + return i.value +} + +fn process(i Item) { + n := i.unwrap() + println(n) + assert n == 5 +} + +fn test_generic_fn_infer_nested_struct() { + item := Item{ + value: 5 + } + process(item) +}