diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 94989b7528c0a8..fdff9d5dd7817e 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -115,9 +115,17 @@ fn (mut g Gen) expr_opt_with_cast(expr ast.Expr, expr_typ ast.Type, ret_typ ast. g.write('_option_ok(&(${styp}[]) {') } if expr is ast.CastExpr && expr_typ.has_flag(.option) { - g.write('*((${g.base_type(expr_typ)}*)') - g.expr(expr) - g.write('.data)') + ret_sym := g.table.sym(ret_typ) + 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)) + } else { + g.write('*((${g.base_type(expr_typ)}*)') + g.expr(expr) + g.write('.data)') + } } else { old_inside_opt_or_res := g.inside_opt_or_res g.inside_opt_or_res = false diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 5532782035ae7f..fd3f8156be78b5 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2585,7 +2585,7 @@ struct SumtypeCastingFn { fn (mut g Gen) get_sumtype_casting_fn(got_ ast.Type, exp_ ast.Type) string { mut got, exp := got_.idx_type(), exp_.idx_type() - i := int(got) | int(u32(exp) << 17) | int(u32(exp_.has_flag(.option)) << 16) + i := int(got) | int(u32(exp) << 18) | int(u32(exp_.has_flag(.option)) << 17) | int(u32(got_.has_flag(.option)) << 16) exp_sym := g.table.sym(exp) mut got_sym := g.table.sym(got) cname := if exp == ast.int_type_idx { diff --git a/vlib/v/tests/options/option_sumtype_option_variant_test.v b/vlib/v/tests/options/option_sumtype_option_variant_test.v new file mode 100644 index 00000000000000..549bd83b05f6c1 --- /dev/null +++ b/vlib/v/tests/options/option_sumtype_option_variant_test.v @@ -0,0 +1,12 @@ +type Any = ?int | string | ?string + +fn test_main() { + b := ?Any(?string('bar')) + assert b?.str() == "Any(Option('bar'))" + + c := ?Any(string('baz')) + assert c?.str() == "Any('baz')" + + d := ?Any('baz') + assert d?.str() == "Any('baz')" +}