diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 09ea5516d9..6f8190536c 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -77,9 +77,9 @@ pub: expr Expr pos token.Position comments []Comment - is_expr bool pub mut: - typ Type + is_expr bool + typ Type } pub struct IntegerLiteral { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 6e0873b7a3..55f3ad82f5 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3504,7 +3504,23 @@ fn (mut c Checker) stmt(node ast.Stmt) { ast.ExprStmt { node.typ = c.expr(node.expr) c.expected_type = ast.void_type - c.check_expr_opt_call(node.expr, ast.void_type) + mut or_typ := ast.void_type + match node.expr { + ast.IndexExpr { + if node.expr.or_expr.kind != .absent { + node.is_expr = true + or_typ = node.typ + } + } + ast.PrefixExpr { + if node.expr.or_block.kind != .absent { + node.is_expr = true + or_typ = node.typ + } + } + else {} + } + c.check_expr_opt_call(node.expr, or_typ) // TODO This should work, even if it's prolly useless .-. // node.typ = c.check_expr_opt_call(node.expr, ast.void_type) } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 78a9e59de0..a4c2412f19 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3832,6 +3832,9 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) { } g.writeln('/*lock*/ {') g.stmts_with_tmp_var(node.stmts, tmp_result) + if node.is_expr { + g.writeln(';') + } g.writeln('}') if node.lockeds.len == 0 { // this should not happen diff --git a/vlib/v/tests/shared_lock_expr_test.v b/vlib/v/tests/shared_lock_expr_test.v index fb1edc3cf8..13376cb62a 100644 --- a/vlib/v/tests/shared_lock_expr_test.v +++ b/vlib/v/tests/shared_lock_expr_test.v @@ -65,3 +65,59 @@ fn test_mult_ret_method() { assert b == 13.125 assert c == -7.5 } + +fn test_shared_lock_map_index_expr() { + shared m := map{ + 'qwe': 'asd' + } + for key in ['fdf', 'qwe'] { + v := rlock m { + m[key] or { 'key not found' } + } + if key == 'qwe' { + assert v == 'asd' + } else { + assert v == 'key not found' + } + } +} + +fn test_shared_lock_array_index_expr() { + shared a := [-12.5, 6.25] + for i in -2 .. 4 { + v := rlock a { + a[i] or { 23.75 } + } + if i == 0 { + assert v == -12.5 + } else if i == 1 { + assert v == 6.25 + } else { + assert v == 23.75 + } + } +} + +struct DummySt { + a int +} + +fn test_shared_lock_chan_rec_expr() { + ch := chan int{cap: 10} + shared st := DummySt{} + ch <- 7 + ch <- -13 + ch.close() + for i in 0 .. 3 { + v := rlock st { + <-ch or { -17 } + } + if i == 0 { + assert v == 7 + } else if i == 1 { + assert v == -13 + } else { + assert v == -17 + } + } +}