mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser, cgen: fix anon fn optional call in if expr (#16803)
This commit is contained in:
@@ -652,7 +652,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
g.write(tmp_var)
|
g.write(tmp_var)
|
||||||
} else {
|
} else if node.or_block.kind == .absent {
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
}
|
}
|
||||||
} else if node.left is ast.IndexExpr && node.name == '' {
|
} else if node.left is ast.IndexExpr && node.name == '' {
|
||||||
@@ -695,6 +695,9 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||||||
g.write('${tmp_opt} = ')
|
g.write('${tmp_opt} = ')
|
||||||
} else {
|
} else {
|
||||||
g.write('${styp} ${tmp_opt} = ')
|
g.write('${styp} ${tmp_opt} = ')
|
||||||
|
if node.left is ast.AnonFn {
|
||||||
|
g.expr(node.left)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if node.is_method && !node.is_field {
|
if node.is_method && !node.is_field {
|
||||||
|
|||||||
@@ -387,11 +387,35 @@ pub fn (mut p Parser) check_expr(precedence int) !ast.Expr {
|
|||||||
pos := p.tok.pos()
|
pos := p.tok.pos()
|
||||||
args := p.call_args()
|
args := p.call_args()
|
||||||
p.check(.rpar)
|
p.check(.rpar)
|
||||||
|
mut or_kind := ast.OrKind.absent
|
||||||
|
mut or_stmts := []ast.Stmt{} // TODO remove unnecessary allocations by just using .absent
|
||||||
|
mut or_pos := p.tok.pos()
|
||||||
|
if p.tok.kind == .key_orelse {
|
||||||
|
// `foo() or {}``
|
||||||
|
or_kind = .block
|
||||||
|
or_stmts, or_pos = p.or_block(.with_err_var)
|
||||||
|
}
|
||||||
|
if p.tok.kind in [.question, .not] {
|
||||||
|
is_not := p.tok.kind == .not
|
||||||
|
// `foo()?`
|
||||||
|
p.next()
|
||||||
|
if p.inside_defer {
|
||||||
|
p.error_with_pos('error propagation not allowed inside `defer` blocks',
|
||||||
|
p.prev_tok.pos())
|
||||||
|
}
|
||||||
|
or_kind = if is_not { .propagate_result } else { .propagate_option }
|
||||||
|
}
|
||||||
|
|
||||||
node = ast.CallExpr{
|
node = ast.CallExpr{
|
||||||
name: 'anon'
|
name: 'anon'
|
||||||
left: node
|
left: node
|
||||||
args: args
|
args: args
|
||||||
pos: pos
|
pos: pos
|
||||||
|
or_block: ast.OrExpr{
|
||||||
|
stmts: or_stmts
|
||||||
|
kind: or_kind
|
||||||
|
pos: or_pos
|
||||||
|
}
|
||||||
scope: p.scope
|
scope: p.scope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
35
vlib/v/tests/anon_fn_optional_call_in_if_expr_test.v
Normal file
35
vlib/v/tests/anon_fn_optional_call_in_if_expr_test.v
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
fn test_anon_fn_optional_call_in_if_expr_1() {
|
||||||
|
if fn () ?bool {
|
||||||
|
return true
|
||||||
|
}() or { false }
|
||||||
|
{
|
||||||
|
println('ok')
|
||||||
|
assert true
|
||||||
|
} else {
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_anon_fn_optional_call_in_if_expr_2() {
|
||||||
|
if fn () ?bool {
|
||||||
|
return true
|
||||||
|
}()?
|
||||||
|
{
|
||||||
|
println('ok')
|
||||||
|
assert true
|
||||||
|
} else {
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_anon_fn_optional_call_in_if_expr_3() {
|
||||||
|
if fn () !bool {
|
||||||
|
return true
|
||||||
|
}()!
|
||||||
|
{
|
||||||
|
println('ok')
|
||||||
|
assert true
|
||||||
|
} else {
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user