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:
parent
cd4ea16609
commit
36ab78d6da
@ -652,7 +652,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||
g.expr(node.left)
|
||||
g.writeln(';')
|
||||
g.write(tmp_var)
|
||||
} else {
|
||||
} else if node.or_block.kind == .absent {
|
||||
g.expr(node.left)
|
||||
}
|
||||
} 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} = ')
|
||||
} else {
|
||||
g.write('${styp} ${tmp_opt} = ')
|
||||
if node.left is ast.AnonFn {
|
||||
g.expr(node.left)
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
args := p.call_args()
|
||||
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{
|
||||
name: 'anon'
|
||||
left: node
|
||||
args: args
|
||||
pos: pos
|
||||
or_block: ast.OrExpr{
|
||||
stmts: or_stmts
|
||||
kind: or_kind
|
||||
pos: or_pos
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user