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,10 +1625,23 @@ 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 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 {
if fn_def := g.table.find_fn(node.name) { if fn_def := g.table.find_fn(node.name) {
mut muttable := unsafe { &ast.Table(g.table) } mut muttable := unsafe { &ast.Table(g.table) }
if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type, fn_def.generic_names, if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type,
node.concrete_types) fn_def.generic_names, node.concrete_types)
{ {
arr_info.elem_type = utyp arr_info.elem_type = utyp
} }
@ -1636,6 +1649,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
g.error('unable to find function $node.name', node.pos) 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)
if (g.pref.translated || g.file.is_translated) && args.len == 1 { if (g.pref.translated || g.file.is_translated) && args.len == 1 {
// Handle `foo(c'str')` for `fn foo(args ...&u8)` // Handle `foo(c'str')` for `fn foo(args ...&u8)`

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]
}