Skip to content

Commit 3e40cd5

Browse files
authored
ast, checker, cgen: fix error for go anon fn variable call (#13776)
1 parent c05634e commit 3e40cd5

File tree

4 files changed

+26
-0
lines changed

4 files changed

+26
-0
lines changed

vlib/v/ast/ast.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ pub mut:
557557
name string // left.name()
558558
is_method bool
559559
is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe)
560+
is_fn_var bool // fn variable
560561
is_keep_alive bool // GC must not free arguments before fn returns
561562
is_noreturn bool // whether the function/method is marked as [noreturn]
562563
is_ctor_new bool // if JS ctor calls requires `new` before call, marked as `[use_new]` in V
@@ -568,6 +569,7 @@ pub mut:
568569
left_type Type // type of `user`
569570
receiver_type Type // User
570571
return_type Type
572+
fn_var_type Type // fn variable type
571573
should_be_skipped bool // true for calls to `[if someflag?]` functions, when there is no `-d someflag`
572574
concrete_types []Type // concrete types, e.g. <int, string>
573575
concrete_list_pos token.Pos

vlib/v/checker/fn.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,13 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
600600
match obj {
601601
ast.GlobalField {
602602
typ = obj.typ
603+
node.is_fn_var = true
604+
node.fn_var_type = typ
603605
}
604606
ast.Var {
605607
typ = if obj.smartcasts.len != 0 { obj.smartcasts.last() } else { obj.typ }
608+
node.is_fn_var = true
609+
node.fn_var_type = typ
606610
}
607611
else {}
608612
}

vlib/v/gen/c/cgen.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5106,6 +5106,8 @@ fn (mut g Gen) go_expr(node ast.GoExpr) {
51065106
} else if mut expr.left is ast.AnonFn {
51075107
g.gen_anon_fn_decl(mut expr.left)
51085108
name = expr.left.decl.name
5109+
} else if expr.is_fn_var {
5110+
name = g.table.sym(expr.fn_var_type).name
51095111
}
51105112
name = util.no_dots(name)
51115113
if g.pref.obfuscate && g.cur_mod.name == 'main' && name.starts_with('main__') {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fn sum(a int, b int) int {
2+
// Simply proxy the function into an anonymous function for demo purposes
3+
sum_func := fn (a int, b int) int {
4+
return a + b
5+
}
6+
7+
// and run it concurrently
8+
g := go sum_func(a, b)
9+
10+
result := g.wait()
11+
return result
12+
}
13+
14+
fn test_go_anon_fn_variable_call() {
15+
ret := sum(22, 33)
16+
println(ret)
17+
assert ret == 55
18+
}

0 commit comments

Comments
 (0)