ast, cgen: fix generic method with variadic generic argument (#14404)
parent
ef6225c542
commit
d59f4e9479
|
@ -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 {}
|
||||||
|
|
|
@ -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)`
|
||||||
|
|
|
@ -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]
|
||||||
|
}
|
Loading…
Reference in New Issue