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

master
yuyi 2022-05-16 17:26:38 +08:00 committed by GitHub
parent ef6225c542
commit d59f4e9479
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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 param.typ = pt
} }
} }
method.generic_names.clear()
return method return method
} }
else {} else {}

View File

@ -1625,15 +1625,29 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
arr_sym := g.table.sym(varg_type) arr_sym := g.table.sym(varg_type)
mut arr_info := arr_sym.info as ast.Array mut arr_info := arr_sym.info as ast.Array
if varg_type.has_flag(.generic) { if varg_type.has_flag(.generic) {
if fn_def := g.table.find_fn(node.name) { if node.is_method {
mut muttable := unsafe { &ast.Table(g.table) } left_sym := g.table.sym(node.left_type)
if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type, fn_def.generic_names, if fn_def := left_sym.find_method_with_generic_parent(node.name) {
node.concrete_types) mut muttable := unsafe { &ast.Table(g.table) }
{ if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type,
arr_info.elem_type = utyp fn_def.generic_names, node.concrete_types)
{
arr_info.elem_type = utyp
}
} else {
g.error('unable to find method $node.name', node.pos)
} }
} else { } 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) 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]
}