checker,cgen: fix generics with generic_fn type parameter (#10022)

pull/10038/head^2
yuyi 2021-05-08 19:06:56 +08:00 committed by GitHub
parent 82a9add25b
commit 3dfbd2351b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 13 deletions

View File

@ -2276,7 +2276,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
if !found { if !found {
if v := call_expr.scope.find_var(fn_name) { if v := call_expr.scope.find_var(fn_name) {
if v.typ != 0 { 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 { if vts.kind == .function {
info := vts.info as ast.FnType info := vts.info as ast.FnType
func = info.func func = info.func

View File

@ -371,18 +371,11 @@ fn (mut g Gen) fn_args(args []ast.Param, is_variadic bool) ([]string, []string)
if arg_type_sym.kind == .function { if arg_type_sym.kind == .function {
info := arg_type_sym.info as ast.FnType info := arg_type_sym.info as ast.FnType
func := info.func func := info.func
if !info.is_anon { g.write('${g.typ(func.return_type)} (*$caname)(')
g.write(arg_type_name + ' ' + caname) g.definitions.write_string('${g.typ(func.return_type)} (*$caname)(')
g.definitions.write_string(arg_type_name + ' ' + caname) g.fn_args(func.params, func.is_variadic)
fargs << caname g.write(')')
fargtypes << arg_type_name g.definitions.write_string(')')
} 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(')')
}
} else { } else {
s := '$arg_type_name $caname' s := '$arg_type_name $caname'
g.write(s) g.write(s)

View File

@ -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<T>(func T, a int) int {
println(T.name)
return func(a)
}
fn generic_indirect_call<T>(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
}