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) +}