checker: fix generics with generic anon fn parameter (#10101)

pull/10106/head
yuyi 2021-05-14 17:01:57 +08:00 committed by GitHub
parent 4273a9697e
commit b728d89069
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 8 deletions

View File

@ -508,14 +508,12 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
if param.typ.has_flag(.generic) && param_type_sym.name == gt_name {
to_set = c.table.mktyp(arg.typ)
mut sym := c.table.get_type_symbol(arg.typ)
if mut sym.info is ast.FnType {
if !sym.info.is_anon {
sym.info.func.name = ''
idx := c.table.find_or_register_fn_type(c.mod, sym.info.func,
true, false)
to_set = ast.new_type(idx).derive(arg.typ)
}
sym := c.table.get_type_symbol(arg.typ)
if sym.info is ast.FnType {
mut func := sym.info.func
func.name = ''
idx := c.table.find_or_register_fn_type(c.mod, func, true, false)
to_set = ast.new_type(idx).derive(arg.typ)
}
if arg.expr.is_auto_deref_var() {
to_set = to_set.deref()

View File

@ -58,3 +58,48 @@ fn test_generics_with_generics_fn_return_type() {
f = mixed_v2(neg)
assert f(7) == -7
}
fn neg_a(a int) int {
return -a
}
fn neg_b(b int) int {
return -b
}
// assume that "generic" is a heavy function and should be shared
// by *all* callers in this file
[noinline]
fn generic<T>(func T) T {
return func
}
fn test_generics_with_generics_fn_return_type_v2() {
mut f := neg_a
assert f(1) == -1
f = generic(neg_a)
assert f(2) == -2
f = generic(neg_b)
assert f(3) == -3
f = generic(fn (a int) int {
return -a
})
assert f(4) == -4
f = generic(fn (b int) int {
return -b
})
assert f(5) == -5
f = fn (a int) int {
return -a
}
f = generic(f)
assert f(6) == -6
f = fn (b int) int {
return -b
}
f = generic(f)
assert f(7) == -7
}