1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: fix sumtype as cast with calling twice (fix #17156) (#17183)

This commit is contained in:
yuyi 2023-02-02 15:31:11 +08:00 committed by GitHub
parent 988aed0353
commit 90ae3c82c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 16 deletions

View File

@ -230,6 +230,7 @@ const (
'do_not_remove', '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_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/const_and_global_with_same_name_test.v', // error C2099: initializer is not a constant
'vlib/v/tests/sumtype_as_cast_test.v', // error: Compound statement expression cannot support
] ]
skip_on_windows = [ skip_on_windows = [
'do_not_remove', 'do_not_remove',

View File

@ -6088,23 +6088,63 @@ fn (mut g Gen) as_cast(node ast.AsCast) {
mut expr_type_sym := g.table.sym(g.unwrap_generic(node.expr_type)) mut expr_type_sym := g.table.sym(g.unwrap_generic(node.expr_type))
if mut expr_type_sym.info is ast.SumType { if mut expr_type_sym.info is ast.SumType {
dot := if node.expr_type.is_ptr() { '->' } else { '.' } dot := if node.expr_type.is_ptr() { '->' } else { '.' }
if sym.info is ast.FnType { $if !msvc {
g.write('/* as */ (${styp})__as_cast(') if node.expr is ast.CallExpr {
} else { tmp_var := g.new_tmp_var()
g.write('/* as */ *(${styp}*)__as_cast(') 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 {
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} */ ')
}
} $else {
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 // fill as cast name table
for variant in expr_type_sym.info.variants { for variant in expr_type_sym.info.variants {

View File

@ -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
}