diff --git a/cmd/tools/vtest-self.v b/cmd/tools/vtest-self.v index b4c680837f..a3bad72732 100644 --- a/cmd/tools/vtest-self.v +++ b/cmd/tools/vtest-self.v @@ -230,6 +230,7 @@ const ( 'do_not_remove', 'vlib/v/tests/const_fixed_array_containing_references_to_itself_test.v', // error C2099: initializer is not a constant 'vlib/v/tests/const_and_global_with_same_name_test.v', // error C2099: initializer is not a constant + 'vlib/v/tests/sumtype_as_cast_test.v', // error: cannot support compound statement expression ({expr; expr; expr;}) ] skip_on_windows = [ 'do_not_remove', diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index ed1dcb59cb..ab635767cc 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6088,23 +6088,43 @@ fn (mut g Gen) as_cast(node ast.AsCast) { mut expr_type_sym := g.table.sym(g.unwrap_generic(node.expr_type)) if mut expr_type_sym.info is ast.SumType { dot := if node.expr_type.is_ptr() { '->' } else { '.' } - if sym.info is ast.FnType { - g.write('/* as */ (${styp})__as_cast(') + if node.expr is ast.CallExpr && !g.is_cc_msvc { + tmp_var := g.new_tmp_var() + expr_styp := g.typ(node.expr_type) + g.write('({ ${expr_styp} ${tmp_var} = ') + g.expr(node.expr) + g.write('; ') + if sym.info is ast.FnType { + g.write('/* as */ (${styp})__as_cast(') + } else { + g.write('/* as */ *(${styp}*)__as_cast(') + } + g.write(tmp_var) + g.write(dot) + g.write('_${sym.cname},') + g.write(tmp_var) + g.write(dot) + sidx := g.type_sidx(unwrapped_node_typ) + g.write('_typ, ${sidx}); }) /*expected idx: ${sidx}, name: ${sym.name} */ ') } else { - g.write('/* as */ *(${styp}*)__as_cast(') + if sym.info is ast.FnType { + g.write('/* as */ (${styp})__as_cast(') + } else { + g.write('/* as */ *(${styp}*)__as_cast(') + } + g.write('(') + g.expr(node.expr) + g.write(')') + g.write(dot) + g.write('_${sym.cname},') + g.write('(') + g.expr(node.expr) + g.write(')') + g.write(dot) + // g.write('typ, /*expected:*/$node.typ)') + sidx := g.type_sidx(unwrapped_node_typ) + g.write('_typ, ${sidx}) /*expected idx: ${sidx}, name: ${sym.name} */ ') } - g.write('(') - g.expr(node.expr) - g.write(')') - g.write(dot) - g.write('_${sym.cname},') - g.write('(') - g.expr(node.expr) - g.write(')') - g.write(dot) - // g.write('typ, /*expected:*/$node.typ)') - sidx := g.type_sidx(unwrapped_node_typ) - g.write('_typ, ${sidx}) /*expected idx: ${sidx}, name: ${sym.name} */ ') // fill as cast name table for variant in expr_type_sym.info.variants { diff --git a/vlib/v/tests/sumtype_as_cast_test.v b/vlib/v/tests/sumtype_as_cast_test.v new file mode 100644 index 0000000000..a0a7569111 --- /dev/null +++ b/vlib/v/tests/sumtype_as_cast_test.v @@ -0,0 +1,18 @@ +type Sum = int | string + +struct Count { +mut: + count int +} + +fn (mut c Count) ret_sum() Sum { + c.count++ + return c.count +} + +fn test_sumtype_as_cast() { + mut cnt := Count{22} + _ := cnt.ret_sum() as int + println(cnt) + assert cnt.count == 23 +}