mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix if-expression code generation if it evaluates to propagating optional / or block (#12032)
This commit is contained in:
parent
552daea04f
commit
cc4af235f3
@ -4880,6 +4880,8 @@ fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool {
|
|||||||
if left_sym.kind in [.array, .array_fixed, .map] {
|
if left_sym.kind in [.array, .array_fixed, .map] {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
} else if stmt.expr.or_block.kind != .absent {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||||||
&& g.pref.gc_mode in [.boehm_full, .boehm_incr, .boehm_full_opt, .boehm_incr_opt]
|
&& g.pref.gc_mode in [.boehm_full, .boehm_incr, .boehm_full_opt, .boehm_incr_opt]
|
||||||
gen_or := node.or_block.kind != .absent // && !g.is_autofree
|
gen_or := node.or_block.kind != .absent // && !g.is_autofree
|
||||||
is_gen_or_and_assign_rhs := gen_or && !g.discard_or_result
|
is_gen_or_and_assign_rhs := gen_or && !g.discard_or_result
|
||||||
cur_line := if is_gen_or_and_assign_rhs || gen_keep_alive { // && !g.is_autofree {
|
mut cur_line := if is_gen_or_and_assign_rhs || gen_keep_alive { // && !g.is_autofree {
|
||||||
// `x := foo() or { ...}`
|
// `x := foo() or { ...}`
|
||||||
// cut everything that has been generated to prepend optional variable creation
|
// cut everything that has been generated to prepend optional variable creation
|
||||||
line := g.go_before_stmt(0)
|
line := g.go_before_stmt(0)
|
||||||
@ -577,6 +577,9 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||||||
ret_typ = ret_typ.set_flag(.optional)
|
ret_typ = ret_typ.set_flag(.optional)
|
||||||
}
|
}
|
||||||
styp := g.typ(ret_typ)
|
styp := g.typ(ret_typ)
|
||||||
|
if gen_or && !is_gen_or_and_assign_rhs {
|
||||||
|
cur_line = g.go_before_stmt(0)
|
||||||
|
}
|
||||||
g.write('$styp $tmp_opt = ')
|
g.write('$styp $tmp_opt = ')
|
||||||
}
|
}
|
||||||
if node.is_method && !node.is_field {
|
if node.is_method && !node.is_field {
|
||||||
@ -594,19 +597,17 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||||||
// if !g.is_autofree {
|
// if !g.is_autofree {
|
||||||
g.or_block(tmp_opt, node.or_block, node.return_type)
|
g.or_block(tmp_opt, node.or_block, node.return_type)
|
||||||
//}
|
//}
|
||||||
if is_gen_or_and_assign_rhs {
|
unwrapped_typ := node.return_type.clear_flag(.optional)
|
||||||
unwrapped_typ := node.return_type.clear_flag(.optional)
|
unwrapped_styp := g.typ(unwrapped_typ)
|
||||||
unwrapped_styp := g.typ(unwrapped_typ)
|
if unwrapped_typ == ast.void_type {
|
||||||
if unwrapped_typ == ast.void_type {
|
g.write('\n $cur_line')
|
||||||
g.write('\n $cur_line')
|
} else if g.table.get_type_symbol(node.return_type).kind == .multi_return {
|
||||||
} else if g.table.get_type_symbol(node.return_type).kind == .multi_return {
|
g.write('\n $cur_line $tmp_opt /*U*/')
|
||||||
g.write('\n $cur_line $tmp_opt /*U*/')
|
} else {
|
||||||
|
if !g.inside_const {
|
||||||
|
g.write('\n $cur_line (*($unwrapped_styp*)${tmp_opt}.data)')
|
||||||
} else {
|
} else {
|
||||||
if !g.inside_const {
|
g.write('\n $cur_line $tmp_opt')
|
||||||
g.write('\n $cur_line (*($unwrapped_styp*)${tmp_opt}.data)')
|
|
||||||
} else {
|
|
||||||
g.write('\n $cur_line $tmp_opt')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if gen_keep_alive {
|
} else if gen_keep_alive {
|
||||||
|
@ -213,3 +213,24 @@ fn test_if_expr_with_complex_array_methods() {
|
|||||||
println(ret)
|
println(ret)
|
||||||
assert ret == ['a', 'b', 'c']
|
assert ret == ['a', 'b', 'c']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn return_optional() ?int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_if_expr_with_optional() ? {
|
||||||
|
m := map[string]int{}
|
||||||
|
v := if a := m['a'] {
|
||||||
|
println('$a')
|
||||||
|
return_optional() ?
|
||||||
|
} else {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
assert v == 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_if_expr_with_or_block() {
|
||||||
|
arr := ['a']
|
||||||
|
a := if arr.len == 0 || arr[0] == '-' { 123 } else { return_optional() or { -1 } }
|
||||||
|
assert a == 1
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user