From d59f4e9479be8b89e28a8dd6ee4fd57fe84b919d Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 16 May 2022 17:26:38 +0800 Subject: [PATCH] ast, cgen: fix generic method with variadic generic argument (#14404) --- vlib/v/ast/types.v | 1 - vlib/v/gen/c/fn.v | 28 ++++++++++++++----- ...c_method_with_variadic_generic_args_test.v | 17 +++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 vlib/v/tests/generic_method_with_variadic_generic_args_test.v diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 87bfe8c124..428e4a67fa 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -1464,7 +1464,6 @@ pub fn (t &TypeSymbol) find_method_with_generic_parent(name string) ?Fn { param.typ = pt } } - method.generic_names.clear() return method } else {} diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 07b87de831..51685a0bfc 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1625,15 +1625,29 @@ fn (mut g Gen) call_args(node ast.CallExpr) { arr_sym := g.table.sym(varg_type) mut arr_info := arr_sym.info as ast.Array if varg_type.has_flag(.generic) { - if fn_def := g.table.find_fn(node.name) { - mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type, fn_def.generic_names, - node.concrete_types) - { - arr_info.elem_type = utyp + if node.is_method { + left_sym := g.table.sym(node.left_type) + if fn_def := left_sym.find_method_with_generic_parent(node.name) { + mut muttable := unsafe { &ast.Table(g.table) } + if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type, + fn_def.generic_names, node.concrete_types) + { + arr_info.elem_type = utyp + } + } else { + g.error('unable to find method $node.name', node.pos) } } else { - g.error('unable to find function $node.name', node.pos) + if fn_def := g.table.find_fn(node.name) { + mut muttable := unsafe { &ast.Table(g.table) } + if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type, + fn_def.generic_names, node.concrete_types) + { + arr_info.elem_type = utyp + } + } else { + g.error('unable to find function $node.name', node.pos) + } } } elem_type := g.typ(arr_info.elem_type) diff --git a/vlib/v/tests/generic_method_with_variadic_generic_args_test.v b/vlib/v/tests/generic_method_with_variadic_generic_args_test.v new file mode 100644 index 0000000000..492a698523 --- /dev/null +++ b/vlib/v/tests/generic_method_with_variadic_generic_args_test.v @@ -0,0 +1,17 @@ +struct Foo { +mut: + arr []T +} + +fn (mut foo Foo) push(items ...T) { + for item in items { + foo.arr << item + } +} + +fn test_generic_method_with_variadic_args() { + mut f := Foo{} + f.push(1, 2, 3, 5, 8, 13, 21, 34, 55) + println(f.arr) + assert f.arr == [1, 2, 3, 5, 8, 13, 21, 34, 55] +}