ast, cgen: fix generic method with variadic generic argument (#14404)

yuyi 2022-05-16 17:26:38 +08:00 committed by Jef Roosens
parent f1b35aff22
commit cdfdf19697
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
3 changed files with 38 additions and 8 deletions

View File

@ -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 {}

View File

@ -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)

View File

@ -0,0 +1,17 @@
struct Foo<T> {
mut:
arr []T
}
fn (mut foo Foo<T>) push<T>(items ...T) {
for item in items {
foo.arr << item
}
}
fn test_generic_method_with_variadic_args() {
mut f := Foo<int>{}
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]
}