From 0632822fd40a1a7753465ae95a114876028b17ef Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 8 Feb 2025 15:31:23 -0300 Subject: [PATCH] cgen: fix codegen for sumtype cast from option variants on map_set (fix #23654) (#23669) --- vlib/v/gen/c/assign.v | 4 ++-- vlib/v/gen/c/cgen.v | 15 +++++++++------ vlib/v/tests/options/option_sumtype_map_test.v | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 vlib/v/tests/options/option_sumtype_map_test.v diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 7bffec34f5..c670928cb0 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -119,8 +119,8 @@ fn (mut g Gen) expr_opt_with_cast(expr ast.Expr, expr_typ ast.Type, ret_typ ast. if ret_sym.kind == .sum_type { exp_sym := g.table.sym(expr_typ) fname := g.get_sumtype_casting_fn(expr_typ, ret_typ) - g.call_cfn_for_casting_expr(fname, expr, ret_typ.is_ptr(), ret_sym.cname, - expr_typ.is_ptr(), exp_sym.kind == .function, g.styp(expr_typ)) + g.call_cfn_for_casting_expr(fname, expr, ret_typ, ret_sym.cname, expr_typ.is_ptr(), + exp_sym.kind == .function, g.styp(expr_typ)) } else { g.write('*((${g.base_type(expr_typ)}*)') g.expr(expr) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 1512c05952..30a92ce399 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2702,11 +2702,11 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) { g.auto_fn_definitions << sb.str() } -fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp_is_ptr bool, exp_styp string, +fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Type, exp_styp string, got_is_ptr bool, got_is_fn bool, got_styp string) { mut rparen_n := 1 is_comptime_variant := expr is ast.Ident && g.comptime.is_comptime_variant_var(expr) - if exp_is_ptr { + if exp.is_ptr() { g.write('HEAP(${exp_styp}, ') rparen_n++ } @@ -2744,7 +2744,10 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp_is_ptr ast.void_type) g.write(g.type_default(ctyp)) } else { + old_left_is_opt := g.left_is_opt + g.left_is_opt = !exp.has_flag(.option) g.expr(expr) + g.left_is_opt = old_left_is_opt } g.write(')'.repeat(rparen_n)) } @@ -2838,8 +2841,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ if exp_sym.info.is_generic { fname = g.generic_fn_name(exp_sym.info.concrete_types, fname) } - g.call_cfn_for_casting_expr(fname, expr, expected_is_ptr, exp_styp, true, - false, got_styp) + g.call_cfn_for_casting_expr(fname, expr, expected_type, exp_styp, true, false, + got_styp) g.inside_cast_in_heap-- } else { got_styp := g.cc_type(got_type, true) @@ -2865,7 +2868,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ return } } - g.call_cfn_for_casting_expr(fname, expr, expected_is_ptr, exp_styp, got_is_ptr, + g.call_cfn_for_casting_expr(fname, expr, expected_type, exp_styp, got_is_ptr, false, got_styp) } return @@ -2930,7 +2933,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ g.write('${fname}(&${tmp_var})') return } else { - g.call_cfn_for_casting_expr(fname, expr, expected_is_ptr, unwrapped_exp_sym.cname, + g.call_cfn_for_casting_expr(fname, expr, expected_type, unwrapped_exp_sym.cname, got_is_ptr, got_is_fn, got_styp) } } diff --git a/vlib/v/tests/options/option_sumtype_map_test.v b/vlib/v/tests/options/option_sumtype_map_test.v new file mode 100644 index 0000000000..9b5eacacd3 --- /dev/null +++ b/vlib/v/tests/options/option_sumtype_map_test.v @@ -0,0 +1,16 @@ +type Any = ?int | ?string + +fn test_main() { + nothing := ?int(none) + zero := ?int(0) + one := ?string('one') + ten := ?int(10) + + mut m := map[string]Any{} + m['nothing'] = Any(nothing) + m['zero'] = Any(zero) + m['one'] = Any(one) + m['ten'] = Any(ten) + + assert m.str() == "{'nothing': Any(Option(none)), 'zero': Any(Option(0)), 'one': Any(Option('one')), 'ten': Any(Option(10))}" +}