Skip to content

Commit ee2a572

Browse files
gen: fix assigning an anon fn to a struct field (#6965)
1 parent cbe607b commit ee2a572

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

vlib/v/gen/cgen.v

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,8 +1522,8 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
15221522
g.write('static ')
15231523
}
15241524
mut return_type := table.void_type
1525-
op := if assign_stmt.op == .decl_assign { token.Kind.assign } else { assign_stmt.op }
15261525
is_decl := assign_stmt.op == .decl_assign
1526+
op := if is_decl { token.Kind.assign } else { assign_stmt.op }
15271527
right_expr := assign_stmt.right[0]
15281528
match right_expr {
15291529
ast.CallExpr { return_type = right_expr.return_type }
@@ -1756,12 +1756,18 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
17561756
if blank_assign {
17571757
g.write('{')
17581758
}
1759-
ret_styp := g.typ(val.decl.return_type)
1760-
g.write('$ret_styp (*$ident.name) (')
1761-
def_pos := g.definitions.len
1762-
g.fn_args(val.decl.params, val.decl.is_variadic)
1763-
g.definitions.go_back(g.definitions.len - def_pos)
1764-
g.write(') = ')
1759+
// if it's a decl assign (`:=`) or a blank assignment `_ =`/`_ :=` then generate `void (*ident) (args) =`
1760+
if (is_decl || blank_assign) && left is ast.Ident {
1761+
ret_styp := g.typ(val.decl.return_type)
1762+
g.write('$ret_styp (*$ident.name) (')
1763+
def_pos := g.definitions.len
1764+
g.fn_args(val.decl.params, val.decl.is_variadic)
1765+
g.definitions.go_back(g.definitions.len - def_pos)
1766+
g.write(') = ')
1767+
} else {
1768+
g.expr(left)
1769+
g.write(' = ')
1770+
}
17651771
g.expr(val)
17661772
g.writeln(';')
17671773
if blank_assign {

vlib/v/tests/anon_fn_test.v

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,16 @@ fn test_go_anon_fn() {
88
}(mut wg)
99
wg.wait()
1010
}
11+
12+
struct AnonFnWrapper {
13+
mut:
14+
fn_ fn () bool
15+
}
16+
17+
fn test_anon_assign_struct() {
18+
mut w := AnonFnWrapper{}
19+
w.fn_ = fn () bool {
20+
return true
21+
}
22+
assert w.fn_()
23+
}

0 commit comments

Comments
 (0)