From 6e46933c554743c4d2d90b23561b611e9b5fd8f2 Mon Sep 17 00:00:00 2001 From: shove Date: Sat, 15 Oct 2022 00:54:13 +0800 Subject: [PATCH] cgen: fix `or {}` handling, when waiting for a single go thread, of a function returning `!Type` (fix #16065) (#16073) --- vlib/v/gen/c/fn.v | 12 ++++++++++-- vlib/v/tests/go_wait_option_test.v | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 3ff9b071d7..e679e7d69b 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1885,12 +1885,20 @@ fn (mut g Gen) go_expr(node ast.GoExpr) { g.writeln('$arg_tmp_var->ret_ptr = malloc(sizeof($s_ret_typ));') } is_opt := node.call_expr.return_type.has_flag(.optional) + is_res := node.call_expr.return_type.has_flag(.result) mut gohandle_name := '' if node.call_expr.return_type == ast.void_type { - gohandle_name = if is_opt { '__v_thread_Option_void' } else { '__v_thread' } + if is_opt { + gohandle_name = '__v_thread_Option_void' + } else if is_res { + gohandle_name = '__v_thread_Result_void' + } else { + gohandle_name = '__v_thread' + } } else { opt := if is_opt { '${option_name}_' } else { '' } - gohandle_name = '__v_thread_$opt${g.table.sym(g.unwrap_generic(node.call_expr.return_type)).cname}' + res := if is_res { '${result_name}_' } else { '' } + gohandle_name = '__v_thread_$opt$res${g.table.sym(g.unwrap_generic(node.call_expr.return_type)).cname}' } if g.pref.os == .windows { simple_handle := if node.is_expr && node.call_expr.return_type != ast.void_type { diff --git a/vlib/v/tests/go_wait_option_test.v b/vlib/v/tests/go_wait_option_test.v index 9912b5432a..f1c05a1d54 100644 --- a/vlib/v/tests/go_wait_option_test.v +++ b/vlib/v/tests/go_wait_option_test.v @@ -80,3 +80,29 @@ fn test_array_val_interate() { assert res[1] == 0.0 assert res[2] == 1.5 } + +// For issue 16065 +fn get_only_a_option_return(return_none bool) ? { + if return_none { + return + } + return error('msg') +} + +fn get_only_a_result_return() ! { + return error('msg') +} + +fn test_only_a_option_return() { + t1 := go get_only_a_option_return(true) + t1.wait() or { assert false } + t2 := go get_only_a_option_return(false) + t2.wait() or { assert true } + assert true +} + +fn test_only_a_result_return() { + t := go get_only_a_result_return() + t.wait() or { assert true } + assert true +}