diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 5f4fcab6d564d6..438c55491315c4 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4785,6 +4785,19 @@ fn (mut g Gen) return_stmt(node ast.Return) { } else if sym.kind == .alias && fn_return_is_fixed_array { ret_typ = '_v_' + g.typ((sym.info as ast.Alias).parent_type) } + if node.exprs.len == 1 { + // `return fn_call_opt()` + if (fn_return_is_option || fn_return_is_result) && node.exprs[0] is ast.CallExpr + && node.exprs[0].return_type == g.fn_decl.return_type + && node.exprs[0].or_block.kind == .absent { + g.write('${ret_typ} ${tmpvar} = ') + g.expr(node.exprs[0]) + g.writeln(';') + g.write_defer_stmts_when_needed() + g.writeln('return ${tmpvar};') + return + } + } mut use_tmp_var := g.defer_stmts.len > 0 || g.defer_profile_code.len > 0 || g.cur_lock.lockeds.len > 0 || (fn_return_is_multi && node.exprs.len >= 1 && fn_return_is_option) diff --git a/vlib/v/tests/return_option_call_test.v b/vlib/v/tests/return_option_call_test.v new file mode 100644 index 00000000000000..d547510843d74c --- /dev/null +++ b/vlib/v/tests/return_option_call_test.v @@ -0,0 +1,17 @@ +fn issue(data string) ?(int, string) { + if data.len == 0 { + return none + } + return data.len, data +} + +fn wrapper(data string) ?(int, string) { + return issue(data) +} + +fn test_return_option_call() { + dump(wrapper('issue')) + dump(wrapper('foobar')) + dump(wrapper('')) + assert true +}