diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 5c628119640c24..ba02351fa76a37 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -799,32 +799,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { ret_styp := g.styp(g.unwrap_generic(val_type)) g.write('${ret_styp} ${fn_name}') } else { - ret_styp := g.styp(right_sym.info.func.return_type) - mut call_conv := '' - mut msvc_call_conv := '' - for attr in right_sym.info.func.attrs { - match attr.name { - 'callconv' { - if g.is_cc_msvc { - msvc_call_conv = '__${attr.arg} ' - } else { - call_conv = '${attr.arg}' - } - } - else {} - } - } - call_conv_attribute_suffix := if call_conv.len != 0 { - '__attribute__((${call_conv}))' - } else { - '' - } - g.write('${ret_styp} (${msvc_call_conv}*${fn_name}) (') - def_pos := g.definitions.len - g.fn_decl_params(right_sym.info.func.params, unsafe { nil }, false, - false) - g.definitions.go_back(g.definitions.len - def_pos) - g.write(')${call_conv_attribute_suffix}') + g.write_fntype_decl(fn_name, right_sym.info) } } else { if is_decl { @@ -872,7 +847,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } } } else { - g.write('${styp} ') + g.write('${styp}/**/ ') } } if is_auto_heap && !(val_type.is_ptr() && val_type.has_flag(.option)) { diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 2da8a8de742126..852c38557883e7 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -3049,3 +3049,31 @@ fn (mut g Gen) write_fn_attrs(attrs []ast.Attr) string { fn call_convention_attribute(cconvention string, is_cc_msvc bool) string { return if is_cc_msvc { '__${cconvention} ' } else { '__attribute__((${cconvention})) ' } } + +fn (mut g Gen) write_fntype_decl(fn_name string, info ast.FnType) { + ret_styp := g.styp(info.func.return_type) + mut call_conv := '' + mut msvc_call_conv := '' + for attr in info.func.attrs { + match attr.name { + 'callconv' { + if g.is_cc_msvc { + msvc_call_conv = '__${attr.arg} ' + } else { + call_conv = '${attr.arg}' + } + } + else {} + } + } + call_conv_attribute_suffix := if call_conv.len != 0 { + '__attribute__((${call_conv}))' + } else { + '' + } + g.write('${ret_styp} (${msvc_call_conv}*${fn_name}) (') + def_pos := g.definitions.len + g.fn_decl_params(info.func.params, unsafe { nil }, false, false) + g.definitions.go_back(g.definitions.len - def_pos) + g.write(')${call_conv_attribute_suffix}') +} diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index 709f7c67894050..aeab75e1757d6b 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -395,7 +395,13 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { } else { '-> ' } - g.writeln('\t${base_type} ${left_var_name} = *(${base_type}*)${var_name}${dot_or_ptr}data;') + expr_sym := g.table.sym(branch.cond.expr_type) + if expr_sym.info is ast.FnType { + g.write_fntype_decl(left_var_name, expr_sym.info) + } else { + g.write('\t${base_type} ${left_var_name}') + } + g.writeln(' = *(${base_type}*)${var_name}${dot_or_ptr}data;') } } else if branch.cond.vars.len > 1 { sym := g.table.sym(branch.cond.expr_type) diff --git a/vlib/v/tests/options/option_fn_guard_test.v b/vlib/v/tests/options/option_fn_guard_test.v new file mode 100644 index 00000000000000..357bffa7eb1ba1 --- /dev/null +++ b/vlib/v/tests/options/option_fn_guard_test.v @@ -0,0 +1,17 @@ +type MyFn = fn () + +fn hello() {} + +fn get_ptr() ?&MyFn { + return &hello +} + +fn test_main() { + if p := get_ptr() { + dump(p) + p() + } + + p2 := get_ptr() or { return } + p2() +}