diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 5049b8b242..d1c887351a 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1875,7 +1875,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. // resolve generic fn return type if func.generic_names.len > 0 && node.return_type != ast.void_type { - ret_type := c.resolve_fn_return_type(func, node) + ret_type := c.resolve_fn_return_type(func, node, concrete_types) c.register_trace_call(node, func) node.return_type = ret_type return ret_type @@ -2670,7 +2670,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) } // resolve generic fn return type if method_generic_names_len > 0 && method.return_type.has_flag(.generic) { - ret_type := c.resolve_fn_return_type(method, node) + ret_type := c.resolve_fn_return_type(method, node, concrete_types) c.register_trace_call(node, method) node.return_type = ret_type return ret_type @@ -3771,11 +3771,9 @@ fn scope_register_var_name(mut s ast.Scope, pos token.Pos, typ ast.Type, name st } // resolve_fn_return_type resolves the generic return type of fn with its related CallExpr -fn (mut c Checker) resolve_fn_return_type(func &ast.Fn, node ast.CallExpr) ast.Type { +fn (mut c Checker) resolve_fn_return_type(func &ast.Fn, node ast.CallExpr, concrete_types []ast.Type) ast.Type { mut ret_type := func.return_type if node.is_method { - // resolve possible generic types - concrete_types := node.concrete_types.map(c.unwrap_generic(it)) // generic method being called from a non-generic func if func.generic_names.len > 0 && func.return_type.has_flag(.generic) && c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len == 0 { @@ -3796,7 +3794,6 @@ fn (mut c Checker) resolve_fn_return_type(func &ast.Fn, node ast.CallExpr) ast.T } } } else { - concrete_types := node.concrete_types.map(c.unwrap_generic(it)) // generic func called from non-generic func if node.concrete_types.len > 0 && func.return_type != 0 && c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len == 0 { diff --git a/vlib/v/tests/generics/generic_return_array_generic_test.v b/vlib/v/tests/generics/generic_return_array_generic_test.v new file mode 100644 index 0000000000..45a4b60cec --- /dev/null +++ b/vlib/v/tests/generics/generic_return_array_generic_test.v @@ -0,0 +1,19 @@ +module main + +struct Test { +} + +fn (mut t Test) decode_array[X](x []X) []X { + println('second: x.typename = ${typeof(x).name}') + return x +} + +fn (mut t Test) decode[T]() T { + return t.decode_array(T{}) +} + +fn test_main() { + mut x := Test{} + x.decode[[]u8]() + x.decode[[]int]() +}