9942 commits 0 issues 0 pull requests 439 contributors 0 branches 0 releases
Additions: 51 Deletions: 8
vlib/v/checker/check_types.v
1
2 if param.typ.has_flag(.generic) && param_type_sym.name == gt_name {
3 to_set = c.table.mktyp(arg.typ)
4- mut sym := c.table.get_type_symbol(arg.typ)
5- if mut sym.info is ast.FnType {
6- if !sym.info.is_anon {
7- sym.info.func.name = ''
8- idx := c.table.find_or_register_fn_type(c.mod, sym.info.func,
9- true, false)
10- to_set = ast.new_type(idx).derive(arg.typ)
11- }
12+ sym := c.table.get_type_symbol(arg.typ)
13+ if sym.info is ast.FnType {
14+ mut func := sym.info.func
15+ func.name = ''
16+ idx := c.table.find_or_register_fn_type(c.mod, func, true, false)
17+ to_set = ast.new_type(idx).derive(arg.typ)
18 }
19 if arg.expr.is_auto_deref_var() {
20 to_set = to_set.deref()
21
vlib/v/tests/generics_with_generics_fn_return_generics_fn_type_test.v
1 f = mixed_v2(neg)
2 assert f(7) == -7
3 }
4+
5+fn neg_a(a int) int {
6+ return -a
7+}
8+
9+fn neg_b(b int) int {
10+ return -b
11+}
12+
13+// assume that "generic" is a heavy function and should be shared
14+// by *all* callers in this file
15+[noinline]
16+fn generic<T>(func T) T {
17+ return func
18+}
19+
20+fn test_generics_with_generics_fn_return_type_v2() {
21+ mut f := neg_a
22+ assert f(1) == -1
23+
24+ f = generic(neg_a)
25+ assert f(2) == -2
26+ f = generic(neg_b)
27+ assert f(3) == -3
28+
29+ f = generic(fn (a int) int {
30+ return -a
31+ })
32+ assert f(4) == -4
33+ f = generic(fn (b int) int {
34+ return -b
35+ })
36+ assert f(5) == -5
37+
38+ f = fn (a int) int {
39+ return -a
40+ }
41+ f = generic(f)
42+ assert f(6) == -6
43+ f = fn (b int) int {
44+ return -b
45+ }
46+ f = generic(f)
47+ assert f(7) == -7
48+}
49