Skip to content

Commit 8a39f8c

Browse files
authored
cgen: fix fn_var_signature() allow option type (fix #26088) (#26120)
1 parent 960c141 commit 8a39f8c

9 files changed

Lines changed: 56 additions & 33 deletions

File tree

‎vlib/v/gen/c/array.v‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,8 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
470470
}
471471

472472
fn (mut g Gen) declare_closure_fn(mut expr ast.AnonFn, var_name string) {
473-
decl_var := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ),
474-
var_name, 0)
473+
decl_var := g.fn_var_signature(expr.typ, expr.decl.return_type, expr.decl.params.map(it.typ),
474+
var_name)
475475
g.write('${decl_var} = ')
476476
g.gen_anon_fn(mut expr)
477477
g.writeln(';')
@@ -552,8 +552,8 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
552552
var_sym := g.table.sym(expr.typ)
553553
if var_sym.info is ast.FnType {
554554
ret_elem_styp = 'voidptr'
555-
closure_var_decl = g.fn_var_signature(var_sym.info.func.return_type, var_sym.info.func.params.map(it.typ),
556-
tmp_map_expr_result_name, 0)
555+
closure_var_decl = g.fn_var_signature(expr.typ, var_sym.info.func.return_type,
556+
var_sym.info.func.params.map(it.typ), tmp_map_expr_result_name)
557557
}
558558
}
559559
}

‎vlib/v/gen/c/assign.v‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
506506
}
507507
// if it's a decl assign (`:=`) or a blank assignment `_ =`/`_ :=` then generate `void (*ident) (args) =`
508508
if (is_decl || blank_assign) && left is ast.Ident {
509-
sig := g.fn_var_signature(val.decl.return_type, val.decl.params.map(it.typ),
510-
ident.name, 0)
509+
sig := g.fn_var_signature(val.typ, val.decl.return_type, val.decl.params.map(it.typ),
510+
ident.name)
511511
g.write(sig + ' = ')
512512
} else {
513513
g.is_assign_lhs = true

‎vlib/v/gen/c/auto_eq_methods.v‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,8 @@ fn (mut g Gen) gen_map_equality_fn(left_type ast.Type) string {
547547
initializer := if !(sym.info is ast.Struct && sym.info.is_empty_struct()) { '0' } else { '' }
548548
if kind == .function {
549549
info := value.sym.info as ast.FnType
550-
sig := g.fn_var_signature(info.func.return_type, info.func.params.map(it.typ),
551-
'v', 0)
550+
sig := g.fn_var_signature(ast.void_type, info.func.return_type, info.func.params.map(it.typ),
551+
'v')
552552
fn_builder.writeln('\t\t${sig} = *(voidptr*)builtin__map_get(${a}, k, &(voidptr[]){ 0 });')
553553
} else {
554554
fn_builder.writeln('\t\t${ptr_value_styp} v = *(${ptr_value_styp}*)builtin__map_get(${a}, k, &(${ptr_value_styp}[]){ ${initializer} });')

‎vlib/v/gen/c/consts_and_globals.v‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, cname string, expr
350350
if expr_sym.kind == .function {
351351
// allow for: `const xyz = abc`, where `abc` is `fn abc() {}`
352352
func := (expr_sym.info as ast.FnType).func
353-
def = g.fn_var_signature(func.return_type, func.params.map(it.typ), cname, 0)
353+
def = g.fn_var_signature(ast.void_type, func.return_type, func.params.map(it.typ),
354+
cname)
354355
}
355356
init_str := init.str().trim_right('\n')
356357
g.global_const_defs[util.no_dots(name)] = GlobalConstDef{

‎vlib/v/gen/c/fn.v‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
308308
g.definitions.write_string('VV_LOC ${trace_fn_ret_type} ${c_name(trace_fn)}(')
309309

310310
if call_fn.is_fn_var {
311-
sig := g.fn_var_signature(call_fn.func.return_type, call_fn.func.params.map(it.typ),
312-
call_fn.name, 0)
311+
sig := g.fn_var_signature(ast.void_type, call_fn.func.return_type, call_fn.func.params.map(it.typ),
312+
call_fn.name)
313313
g.write(sig)
314314
g.definitions.write_string(sig)
315315
} else {
@@ -741,8 +741,8 @@ fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) {
741741
for var in node.inherited_vars {
742742
var_sym := g.table.sym(var.typ)
743743
if var_sym.info is ast.FnType {
744-
mut sig := g.fn_var_signature(var_sym.info.func.return_type, var_sym.info.func.params.map(it.typ),
745-
c_name(var.name), var.typ.nr_muls())
744+
mut sig := g.fn_var_signature(var.typ, var_sym.info.func.return_type,
745+
var_sym.info.func.params.map(it.typ), c_name(var.name))
746746
g.definitions.writeln('\t' + sig + ';')
747747
} else {
748748
styp := g.styp(var.typ)
@@ -880,8 +880,8 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
880880
if node.left is ast.AnonFn {
881881
if node.left.inherited_vars.len > 0 {
882882
tmp_anon_fn_var = g.new_tmp_var()
883-
fn_type := g.fn_var_signature(node.left.decl.return_type, node.left.decl.params.map(it.typ),
884-
tmp_anon_fn_var, 0)
883+
fn_type := g.fn_var_signature(ast.void_type, node.left.decl.return_type, node.left.decl.params.map(it.typ),
884+
tmp_anon_fn_var)
885885
line := g.go_before_last_stmt().trim_space()
886886
g.empty_line = true
887887
g.write('${fn_type} = ')
@@ -913,8 +913,8 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
913913
left_typ := g.table.value_type(node.left.left_type)
914914
tmp_res := g.new_tmp_var()
915915
fn_sym := g.table.sym(left_typ).info as ast.FnType
916-
fn_type := g.fn_var_signature(fn_sym.func.return_type, fn_sym.func.params.map(it.typ),
917-
tmp_res, 0)
916+
fn_type := g.fn_var_signature(ast.void_type, fn_sym.func.return_type, fn_sym.func.params.map(it.typ),
917+
tmp_res)
918918

919919
old_is_fn_index_call := g.is_fn_index_call
920920
g.is_fn_index_call = true

‎vlib/v/gen/c/match.v‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
102102
ret_final_sym := g.table.final_sym(node.return_type)
103103
if !node.return_type.has_option_or_result() && ret_final_sym.kind == .function {
104104
if ret_final_sym.info is ast.FnType {
105-
def := g.fn_var_signature(ret_final_sym.info.func.return_type, ret_final_sym.info.func.params.map(it.typ),
106-
tmp_var, 0)
105+
def := g.fn_var_signature(ast.void_type, ret_final_sym.info.func.return_type,
106+
ret_final_sym.info.func.params.map(it.typ), tmp_var)
107107
func_decl = '${def} = &${g.styp(node.return_type)};'
108108
}
109109
}

‎vlib/v/gen/c/spawn_and_go.v‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
5050
}
5151
} else if mut expr.left is ast.AnonFn {
5252
if expr.left.inherited_vars.len > 0 {
53-
fn_var := g.fn_var_signature(expr.left.decl.return_type, expr.left.decl.params.map(it.typ),
54-
tmp_fn, 0)
53+
fn_var := g.fn_var_signature(ast.void_type, expr.left.decl.return_type, expr.left.decl.params.map(it.typ),
54+
tmp_fn)
5555
g.write('\t${fn_var} = ')
5656
g.gen_anon_fn(mut expr.left)
5757
g.writeln(';')
@@ -65,8 +65,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
6565
if expr.is_fn_var {
6666
fn_sym := g.table.sym(expr.fn_var_type)
6767
func := (fn_sym.info as ast.FnType).func
68-
fn_var := g.fn_var_signature(func.return_type, func.params.map(it.typ), tmp_fn,
69-
0)
68+
fn_var := g.fn_var_signature(ast.void_type, func.return_type, func.params.map(it.typ),
69+
tmp_fn)
7070
g.write('\t${fn_var} = ')
7171
g.expr(expr.left)
7272
g.writeln(';')
@@ -185,11 +185,12 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
185185
if node.call_expr.is_fn_var {
186186
fn_sym := g.table.sym(node.call_expr.fn_var_type)
187187
info := fn_sym.info as ast.FnType
188-
fn_var = g.fn_var_signature(info.func.return_type, info.func.params.map(it.typ),
189-
'fn', 0)
188+
fn_var = g.fn_var_signature(ast.void_type, info.func.return_type, info.func.params.map(it.typ),
189+
'fn')
190190
} else if node.call_expr.left is ast.AnonFn {
191191
f := node.call_expr.left.decl
192-
fn_var = g.fn_var_signature(f.return_type, f.params.map(it.typ), 'fn', 0)
192+
fn_var = g.fn_var_signature(ast.void_type, f.return_type, f.params.map(it.typ),
193+
'fn')
193194
} else {
194195
if node.call_expr.is_method {
195196
rec_sym := g.table.sym(g.unwrap_generic(node.call_expr.receiver_type))
@@ -200,7 +201,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
200201
mut arg_types := f.params.map(it.typ)
201202
arg_types = arg_types.map(muttable.convert_generic_type(it, f.generic_names,
202203
node.call_expr.concrete_types) or { it })
203-
fn_var = g.fn_var_signature(return_type, arg_types, 'fn', 0)
204+
fn_var = g.fn_var_signature(ast.void_type, return_type, arg_types,
205+
'fn')
204206
}
205207
} else {
206208
if f := g.table.find_fn(node.call_expr.name) {
@@ -223,7 +225,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
223225
}
224226
}
225227
}
226-
fn_var = g.fn_var_signature(return_type, arg_types, 'fn', 0)
228+
fn_var = g.fn_var_signature(ast.void_type, return_type, arg_types,
229+
'fn')
227230
}
228231
}
229232
}
@@ -238,8 +241,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
238241
for i, arg in expr.args {
239242
arg_sym := g.table.sym(arg.typ)
240243
if arg_sym.info is ast.FnType {
241-
sig := g.fn_var_signature(arg_sym.info.func.return_type, arg_sym.info.func.params.map(it.typ),
242-
'arg${i + 1}', arg.typ.nr_muls())
244+
sig := g.fn_var_signature(arg.typ, arg_sym.info.func.return_type, arg_sym.info.func.params.map(it.typ),
245+
'arg${i + 1}')
243246
g.type_definitions.writeln('\t' + sig + ';')
244247
} else {
245248
styp := g.styp(arg.typ)

‎vlib/v/gen/c/utils.v‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,19 @@ fn (mut g Gen) unwrap(typ ast.Type) Type {
8484
}
8585

8686
// generate function variable definition, e.g. `void (*var_name) (int, string)`
87-
fn (mut g Gen) fn_var_signature(return_type ast.Type, arg_types []ast.Type, var_name string, nr_muls int) string {
87+
fn (mut g Gen) fn_var_signature(var_type ast.Type, return_type ast.Type, arg_types []ast.Type, var_name string) string {
88+
if var_type.has_flag(.option) {
89+
return '${g.styp(var_type)} ${c_name(var_name)}'
90+
}
8891
ret_styp := g.styp(return_type)
92+
nr_muls := var_type.nr_muls()
8993
mut sig := '${ret_styp} (${'*'.repeat(nr_muls + 1)}${c_name(var_name)}) ('
9094
for j, arg_typ in arg_types {
9195
arg_sym := g.table.sym(arg_typ)
9296
if arg_sym.info is ast.FnType {
9397
func := arg_sym.info.func
94-
arg_sig := g.fn_var_signature(func.return_type, func.params.map(it.typ), '',
95-
arg_typ.nr_muls())
98+
arg_sig := g.fn_var_signature(arg_typ, func.return_type, func.params.map(it.typ),
99+
'')
96100
sig += arg_sig
97101
} else {
98102
arg_styp := g.styp(arg_typ)

‎vlib/v/tests/closure_with_fn_ref_var_test.v‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,18 @@ fn test_closure_with_fn_ref_var() {
2323
assert deref() == 1
2424
assert handler() == 1
2525
}
26+
27+
type Fun = fn () int
28+
29+
fn test_closure_with_fn_ref_var_option() {
30+
opt := ?Fun(f_a)
31+
32+
handler := fn [opt] () int {
33+
if g := opt {
34+
return g()
35+
}
36+
return 0
37+
}
38+
39+
assert handler() == 1
40+
}

0 commit comments

Comments
 (0)