vq / vlib / v / tests / fns / static_method_as_map_arg_test.v
50 lines · 42 sloc · 1.39 KB · b02a629296b932a1b95b2c88257f25ab05466d75
Raw
1// Regression test for a static method used as a first-class value in the
2// builtin array methods (`map`/`filter`/...). It is parsed as an `ast.EnumVal`
3// (same syntax as an enum value, e.g. `Color.red`); when the static method is
4// not yet registered while parsing the call site (forward reference here, or a
5// cross-module reference), the parser cannot emit a function `ast.Ident`, so the
6// checker has to rewrite the resolved value into one. See issue #27328.
7
8fn test_static_method_as_map_arg() {
9 nums := [1, 2, 3]
10 foos := nums.map(Foo.from)
11 assert foos.map(it.x) == [1, 2, 3]
12}
13
14fn test_static_method_as_map_arg_explicit_call() {
15 nums := [1, 2, 3]
16 foos := nums.map(Foo.from(it))
17 assert foos.map(it.x) == [1, 2, 3]
18}
19
20fn test_static_method_as_filter_arg() {
21 nums := [1, 2, 3, 4]
22 odds := nums.filter(is_odd)
23 assert odds == [1, 3]
24}
25
26fn test_aliased_static_method_as_map_arg() {
27 // the static method is reached through a type alias, so it must be resolved
28 // by its real fkey (`Foo__static__from`), not the alias name
29 nums := [1, 2, 3]
30 foos := nums.map(FooAlias.from)
31 assert foos.map(it.x) == [1, 2, 3]
32}
33
34type FooAlias = Foo
35
36// Defined *after* the call sites on purpose, to exercise the forward-reference
37// path (the function is not in the table yet when the calls above are parsed).
38struct Foo {
39 x int
40}
41
42fn Foo.from(n int) Foo {
43 return Foo{
44 x: n
45 }
46}
47
48fn is_odd(n int) bool {
49 return n % 2 == 1
50}
51