diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 5195d75d7edf45..4f787ea53192a4 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1355,16 +1355,20 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return } if node.stmts.len == 0 { if expr is ast.CallExpr && expr.is_return_used { - // x := f() or {} - c.error('assignment requires a non empty `or {}` block', node.pos) + // x := f() or {}, || f() or {} etc + c.error('expression requires a non empty `or {}` block', node.pos) } // allow `f() or {}` return } mut valid_stmts := node.stmts.filter(it !is ast.SemicolonStmt) mut last_stmt := if valid_stmts.len > 0 { valid_stmts.last() } else { node.stmts.last() } - if expr !is ast.CallExpr || (expr is ast.CallExpr && expr.is_return_used) { + if expr is ast.CallExpr && expr.is_return_used { + // requires a block returning an unwrapped type of callexpr return type c.check_or_last_stmt(mut last_stmt, ret_type, expr_return_type.clear_option_and_result()) + } else { + // allow f() or { var = 123 } + c.check_or_last_stmt(mut last_stmt, ast.void_type, expr_return_type.clear_option_and_result()) } } diff --git a/vlib/v/checker/lambda_expr.v b/vlib/v/checker/lambda_expr.v index 12575c5ee0831a..ffa9966954277b 100644 --- a/vlib/v/checker/lambda_expr.v +++ b/vlib/v/checker/lambda_expr.v @@ -68,6 +68,9 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as is_expr: false typ: return_type } + if mut node.expr is ast.CallExpr && node.expr.is_return_used { + node.expr.is_return_used = false + } } else { stmts << ast.Return{ pos: node.pos diff --git a/vlib/v/checker/tests/call_empty_or_block_err.out b/vlib/v/checker/tests/call_empty_or_block_err.out index aaf409e6375b3f..18a9f483fca203 100644 --- a/vlib/v/checker/tests/call_empty_or_block_err.out +++ b/vlib/v/checker/tests/call_empty_or_block_err.out @@ -33,14 +33,14 @@ vlib/v/checker/tests/call_empty_or_block_err.vv:35:2: warning: unused variable: | ^ 36 | foo() or {} 37 | false -vlib/v/checker/tests/call_empty_or_block_err.vv:9:24: error: assignment requires a non empty `or {}` block +vlib/v/checker/tests/call_empty_or_block_err.vv:9:24: error: expression requires a non empty `or {}` block 7 | 8 | fn main() { 9 | a := foo() or { foo() or {} } | ~~~~~ 10 | 11 | // must be error -vlib/v/checker/tests/call_empty_or_block_err.vv:14:9: error: assignment requires a non empty `or {}` block +vlib/v/checker/tests/call_empty_or_block_err.vv:14:9: error: expression requires a non empty `or {}` block 12 | y := if c := foo() { 13 | dump(c) 14 | bar() or {} diff --git a/vlib/v/checker/tests/or_block_check_err.out b/vlib/v/checker/tests/or_block_check_err.out index c4fb27bba829b6..854bbe1d662c32 100644 --- a/vlib/v/checker/tests/or_block_check_err.out +++ b/vlib/v/checker/tests/or_block_check_err.out @@ -1,11 +1,11 @@ -vlib/v/checker/tests/or_block_check_err.vv:6:36: error: assignment requires a non empty `or {}` block +vlib/v/checker/tests/or_block_check_err.vv:6:36: error: expression requires a non empty `or {}` block 4 | 5 | fn main() { 6 | _ = callexpr_with_or_block_call() or {}.replace('a', 'b') | ~~~~~ 7 | _ = (callexpr_with_or_block_call() or {}).replace('a', 'b') 8 | -vlib/v/checker/tests/or_block_check_err.vv:7:37: error: assignment requires a non empty `or {}` block +vlib/v/checker/tests/or_block_check_err.vv:7:37: error: expression requires a non empty `or {}` block 5 | fn main() { 6 | _ = callexpr_with_or_block_call() or {}.replace('a', 'b') 7 | _ = (callexpr_with_or_block_call() or {}).replace('a', 'b') diff --git a/vlib/v/checker/tests/orm_no_default_value.out b/vlib/v/checker/tests/orm_no_default_value.out index 43d11d19b53be4..104496004e15e9 100644 --- a/vlib/v/checker/tests/orm_no_default_value.out +++ b/vlib/v/checker/tests/orm_no_default_value.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/orm_no_default_value.vv:11:4: error: assignment requires a non empty `or {}` block +vlib/v/checker/tests/orm_no_default_value.vv:11:4: error: expression requires a non empty `or {}` block 9 | _ := sql db { 10 | select from Person 11 | } or { diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index b7774a641091a3..bbfbe197ca2bdf 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -1033,7 +1033,7 @@ fn (mut p Parser) lambda_expr() ?ast.LambdaExpr { } } pos_expr := p.tok.pos() - e := p.expr_no_value(0) + e := p.expr(0) pos_end := p.tok.pos() return ast.LambdaExpr{ pos: pos.extend(e.pos())