From 3dfbd2351b1e123e035269c94919cf796b7bf177 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 8 May 2021 19:06:56 +0800 Subject: [PATCH] checker,cgen: fix generics with generic_fn type parameter (#10022) --- vlib/v/checker/checker.v | 2 +- vlib/v/gen/c/fn.v | 17 +++------- ...ics_with_generics_fn_type_parameter_test.v | 34 +++++++++++++++++++ 3 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 vlib/v/tests/generics_with_generics_fn_type_parameter_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b6cc5cfeaa..0197c199c7 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2276,7 +2276,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { if !found { if v := call_expr.scope.find_var(fn_name) { if v.typ != 0 { - vts := c.table.get_type_symbol(v.typ) + vts := c.table.get_type_symbol(c.unwrap_generic(v.typ)) if vts.kind == .function { info := vts.info as ast.FnType func = info.func diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 057a8c3b0a..69a3812295 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -371,18 +371,11 @@ fn (mut g Gen) fn_args(args []ast.Param, is_variadic bool) ([]string, []string) if arg_type_sym.kind == .function { info := arg_type_sym.info as ast.FnType func := info.func - if !info.is_anon { - g.write(arg_type_name + ' ' + caname) - g.definitions.write_string(arg_type_name + ' ' + caname) - fargs << caname - fargtypes << arg_type_name - } else { - g.write('${g.typ(func.return_type)} (*$caname)(') - g.definitions.write_string('${g.typ(func.return_type)} (*$caname)(') - g.fn_args(func.params, func.is_variadic) - g.write(')') - g.definitions.write_string(')') - } + g.write('${g.typ(func.return_type)} (*$caname)(') + g.definitions.write_string('${g.typ(func.return_type)} (*$caname)(') + g.fn_args(func.params, func.is_variadic) + g.write(')') + g.definitions.write_string(')') } else { s := '$arg_type_name $caname' g.write(s) diff --git a/vlib/v/tests/generics_with_generics_fn_type_parameter_test.v b/vlib/v/tests/generics_with_generics_fn_type_parameter_test.v new file mode 100644 index 0000000000..d5a0267187 --- /dev/null +++ b/vlib/v/tests/generics_with_generics_fn_type_parameter_test.v @@ -0,0 +1,34 @@ +fn neg(a int) int { + return -a +} + +fn indirect_call(func fn (int) int, a int) int { + println(typeof(func).name) + return func(a) +} + +fn generic_call(func T, a int) int { + println(T.name) + return func(a) +} + +fn generic_indirect_call(func T, a int) int { + println(T.name) + return indirect_call(func, a) +} + +fn test_generics_with_generics_fn_type_parameter() { + mut ret := 0 + + ret = indirect_call(neg, 2) + println(ret) + assert ret == -2 + + ret = generic_call(neg, 3) + println(ret) + assert ret == -3 + + ret = generic_indirect_call(neg, 4) + println(ret) + assert ret == -4 +}