diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 9973aac9f7..0d03500199 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1084,9 +1084,16 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { } if call_expr.generic_type != table.void_type && f.return_type != 0 { // table.t_type { // Handle `foo() T` => `foo() int` => return int - sym := c.table.get_type_symbol(f.return_type) - if sym.name == 'T' { + return_sym := c.table.get_type_symbol(f.return_type) + if return_sym.name == 'T' { return call_expr.generic_type + } else if return_sym.kind == .array { + elem_info := return_sym.info as table.Array + elem_sym := c.table.get_type_symbol(elem_info.elem_type) + if elem_sym.name == 'T' { + idx := c.table.find_or_register_array(call_expr.generic_type, 1, return_sym.mod) + return table.new_type(idx) + } } } return f.return_type diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 44ddb4a780..cd23e14017 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -77,9 +77,12 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) { } else { name = c_name(name) } + mut type_name := g.typ(it.return_type) if g.cur_generic_type != 0 { // foo() => foo_int(), foo_string() etc - name += '_' + g.typ(g.cur_generic_type) + gen_name := g.typ(g.cur_generic_type) + name += '_' + gen_name + type_name = type_name.replace('T', gen_name) } // if g.pref.show_cc && it.is_builtin { // println(name) @@ -96,7 +99,6 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) { } mut impl_fn_name := if is_live_wrap { 'impl_live_${name}' } else { name } g.last_fn_c_name = impl_fn_name - type_name := g.typ(it.return_type) // if is_live_wrap { if is_livemain { @@ -248,6 +250,11 @@ fn (mut g Gen) fn_args(args []table.Arg, is_variadic bool) ([]string, []string) // if arg.name == 'xxx' { // println('xxx arg type= ' + arg_type_name) // } + if g.cur_generic_type != 0 { + // foo() => foo_int(), foo_string() etc + gen_name := g.typ(g.cur_generic_type) + arg_type_name = arg_type_name.replace('T', gen_name) + } is_varg := i == args.len - 1 && is_variadic if is_varg { varg_type_str := int(arg.typ).str() diff --git a/vlib/v/tests/generics_test.v b/vlib/v/tests/generics_test.v index 5ad70b2634..b9b9241c55 100644 --- a/vlib/v/tests/generics_test.v +++ b/vlib/v/tests/generics_test.v @@ -82,6 +82,21 @@ fn test_create() { mut_arg2(mut u) } +fn return_array(arr []T) []T { + return arr +} + +fn test_return_array() { + a1 := return_array([1, 2, 3]) + assert a1 == [1, 2, 3] + a2 := return_array([1.1, 2.2, 3.3]) + assert a2 == [1.1, 2.2, 3.3] + a3 := return_array(['a', 'b', 'c']) + assert a3 == ['a', 'b', 'c'] + a4 := return_array([true, false, true]) + assert a4 == [true, false, true] +} + /* fn map_f(l []T, f fn(T)U) []U { mut r := []U{}