From 61a4b469a334084fa95c8e830dbc4903527b232b Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 9 Sep 2022 23:23:56 +0800 Subject: [PATCH] cgen: fix nested match expr with optional or result (#15713) --- vlib/v/gen/c/cgen.v | 26 +++++++-- ...ch_expr_nested_with_optional_result_test.v | 57 +++++++++++++++++++ 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 vlib/v/tests/match_expr_nested_with_optional_result_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index f22da3429c..e78d99d180 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1589,9 +1589,16 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool { styp = 'f64' } } - g.write('opt_ok2(&($styp[]) { ') - g.stmt(stmt) - g.writeln(' }, ($c.option_name*)(&$tmp_var), sizeof($styp));') + if stmt.typ.has_flag(.optional) { + g.writeln('') + g.write('$tmp_var = ') + g.expr(stmt.expr) + g.writeln(';') + } else { + g.write('opt_ok2(&($styp[]) { ') + g.expr(stmt.expr) + g.writeln(' }, ($c.option_name*)(&$tmp_var), sizeof($styp));') + } } } } else if g.inside_if_result || g.inside_match_result { @@ -1612,9 +1619,16 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool { styp = 'f64' } } - g.write('opt_ok2(&($styp[]) { ') - g.stmt(stmt) - g.writeln(' }, ($c.result_name*)(&$tmp_var), sizeof($styp));') + if stmt.typ.has_flag(.result) { + g.writeln('') + g.write('$tmp_var = ') + g.expr(stmt.expr) + g.writeln(';') + } else { + g.write('opt_ok2(&($styp[]) { ') + g.expr(stmt.expr) + g.writeln(' }, ($c.result_name*)(&$tmp_var), sizeof($styp));') + } } } } else { diff --git a/vlib/v/tests/match_expr_nested_with_optional_result_test.v b/vlib/v/tests/match_expr_nested_with_optional_result_test.v new file mode 100644 index 0000000000..730daa141f --- /dev/null +++ b/vlib/v/tests/match_expr_nested_with_optional_result_test.v @@ -0,0 +1,57 @@ +// optional +fn foo1() ?int { + return 1 +} + +fn bar1(i int) bool { + return true +} + +fn is_ok1(y int, m int) ?bool { + return match true { + y > 0 { + match m { + 1 { bar1(foo1()?) } + 2 { false } + else { none } + } + } + else { + none + } + } +} + +// result +fn foo2() !int { + return 1 +} + +fn bar2(i int) bool { + return true +} + +fn is_ok2(y int, m int) !bool { + return match true { + y > 0 { + match m { + 1 { bar2(foo2()!) } + 2 { false } + else { error('') } + } + } + else { + error('') + } + } +} + +fn test_match_expr_nested_with_optional_result() { + ret1 := is_ok1(2, 1) or { false } + println(ret1) + assert ret1 + + ret2 := is_ok2(2, 1) or { false } + println(ret2) + assert ret2 +}