From 603469b85684399aa2743eeb9afb7e3dff611412 Mon Sep 17 00:00:00 2001 From: Tim Marston Date: Fri, 3 Feb 2023 06:50:20 +0000 Subject: [PATCH] cgen: don't voidptr cast option/result functions (fix #17204) (#17207) --- vlib/v/gen/c/cgen.v | 3 +- .../if_expr_nested_with_option_result_test.v | 52 ++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index ab635767cc..5b157bb866 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2580,7 +2580,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ return } } - if exp_sym.kind == .function { + if exp_sym.kind == .function && !expected_type.has_flag(.option) + && !expected_type.has_flag(.result) { g.write('(voidptr)') } // no cast diff --git a/vlib/v/tests/if_expr_nested_with_option_result_test.v b/vlib/v/tests/if_expr_nested_with_option_result_test.v index b37346252f..7e5fa3b76a 100644 --- a/vlib/v/tests/if_expr_nested_with_option_result_test.v +++ b/vlib/v/tests/if_expr_nested_with_option_result_test.v @@ -37,11 +37,30 @@ pub fn bar2(i int) !int { } } +pub fn bar3(ok bool) ?fn () string { + return if ok { + fn () string { + return 'yes' + } + } else { + none + } +} + +pub fn bar4(ok bool) !fn () string { + return if ok { + fn () string { + return 'yes' + } + } else { + error('no:error') + } +} + fn test_if_expr_nested_with_option_result() { ret11 := bar1(0) or { 0 } println(ret11) assert ret11 == 2 - ret12 := bar1(1) or { 0 } println(ret12) assert ret12 == 3 @@ -49,8 +68,37 @@ fn test_if_expr_nested_with_option_result() { ret21 := bar2(0) or { 0 } println(ret21) assert ret21 == 2 - ret22 := bar2(1) or { 0 } println(ret22) assert ret22 == 3 + + ret31 := bar3(true) or { + fn () string { + return 'no:default' + } + } + println(ret31()) + assert ret31() == 'yes' + ret32 := bar3(false) or { + fn () string { + return 'no:default' + } + } + println(ret32()) + assert ret32() == 'no:default' + + ret41 := bar4(true) or { + fn [err] () string { + return err.msg() + } + } + println(ret41()) + assert ret41() == 'yes' + ret42 := bar4(false) or { + fn [err] () string { + return err.msg() + } + } + println(ret42()) + assert ret42() == 'no:error' }