Skip to content

Commit e4065bd

Browse files
authored
checker,cgen: fix if expressions in lock expression (#14384)
1 parent c280510 commit e4065bd

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

vlib/v/checker/checker.v

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3537,6 +3537,7 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
35373537
}
35383538

35393539
pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
3540+
expected_type := c.expected_type
35403541
if c.rlocked_names.len > 0 || c.locked_names.len > 0 {
35413542
c.error('nested `lock`/`rlock` not allowed', node.pos)
35423543
}
@@ -3560,16 +3561,17 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
35603561
}
35613562
}
35623563
c.stmts(node.stmts)
3563-
c.rlocked_names = []
3564-
c.locked_names = []
35653564
// handle `x := rlock a { a.getval() }`
35663565
mut ret_type := ast.void_type
35673566
if node.stmts.len > 0 {
35683567
last_stmt := node.stmts.last()
35693568
if last_stmt is ast.ExprStmt {
3570-
ret_type = last_stmt.typ
3569+
c.expected_type = expected_type
3570+
ret_type = c.expr(last_stmt.expr)
35713571
}
35723572
}
3573+
c.rlocked_names = []
3574+
c.locked_names = []
35733575
if ret_type != ast.void_type {
35743576
node.is_expr = true
35753577
}

vlib/v/checker/tests/lock_already_locked.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ vlib/v/checker/tests/lock_already_locked.vv:11:3: error: nested `lock`/`rlock` n
55
| ~~~~~
66
12 | a.x++
77
13 | }
8+
vlib/v/checker/tests/lock_already_locked.vv:12:4: error: a has an `rlock` but needs a `lock`
9+
10 | lock a {
10+
11 | rlock a {
11+
12 | a.x++
12+
| ^
13+
13 | }
14+
14 | }
815
vlib/v/checker/tests/lock_already_locked.vv:15:10: error: `a` is `shared` and must be `rlock`ed or `lock`ed to be used as non-mut argument to print
916
13 | }
1017
14 | }

vlib/v/gen/c/assign.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,8 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) {
456456
}
457457
if val is ast.ArrayInit {
458458
g.array_init(val, ident.name)
459+
} else if val_type.has_flag(.shared_f) {
460+
g.expr_with_cast(val, val_type, var_type)
459461
} else {
460462
g.expr(val)
461463
}

vlib/v/gen/c/if.v

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
7878
g.write(' ? ')
7979
}
8080
prev_expected_cast_type := g.expected_cast_type
81-
if node.is_expr && g.table.sym(node.typ).kind == .sum_type {
81+
if node.is_expr
82+
&& (g.table.sym(node.typ).kind == .sum_type || node.typ.has_flag(.shared_f)) {
8283
g.expected_cast_type = node.typ
8384
}
8485
g.stmts(branch.stmts)
@@ -204,7 +205,8 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
204205
}
205206
if needs_tmp_var {
206207
prev_expected_cast_type := g.expected_cast_type
207-
if node.is_expr && g.table.sym(node.typ).kind == .sum_type {
208+
if node.is_expr
209+
&& (g.table.sym(node.typ).kind == .sum_type || node.typ.has_flag(.shared_f)) {
208210
g.expected_cast_type = node.typ
209211
}
210212
g.stmts_with_tmp_var(branch.stmts, tmp)

vlib/v/tests/shared_if_expr_test.v

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
type AA = bool | int
2+
3+
fn test_shared_if_expr() {
4+
shared a := [1, 2, 3]
5+
b := [4, 5, 6]
6+
c := lock a {
7+
if a == b { a } else { b }
8+
}
9+
assert c == [4, 5, 6]
10+
d := lock a {
11+
if a != b {
12+
a << 5
13+
a
14+
} else {
15+
b
16+
}
17+
}
18+
assert d == [1, 2, 3, 5]
19+
}

0 commit comments

Comments
 (0)