checker,cgen: fix if expressions in lock expression (#14384)
parent
fd17b62ea6
commit
82018034ef
|
@ -3537,6 +3537,7 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
|
pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
|
||||||
|
expected_type := c.expected_type
|
||||||
if c.rlocked_names.len > 0 || c.locked_names.len > 0 {
|
if c.rlocked_names.len > 0 || c.locked_names.len > 0 {
|
||||||
c.error('nested `lock`/`rlock` not allowed', node.pos)
|
c.error('nested `lock`/`rlock` not allowed', node.pos)
|
||||||
}
|
}
|
||||||
|
@ -3560,16 +3561,17 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.stmts(node.stmts)
|
c.stmts(node.stmts)
|
||||||
c.rlocked_names = []
|
|
||||||
c.locked_names = []
|
|
||||||
// handle `x := rlock a { a.getval() }`
|
// handle `x := rlock a { a.getval() }`
|
||||||
mut ret_type := ast.void_type
|
mut ret_type := ast.void_type
|
||||||
if node.stmts.len > 0 {
|
if node.stmts.len > 0 {
|
||||||
last_stmt := node.stmts.last()
|
last_stmt := node.stmts.last()
|
||||||
if last_stmt is ast.ExprStmt {
|
if last_stmt is ast.ExprStmt {
|
||||||
ret_type = last_stmt.typ
|
c.expected_type = expected_type
|
||||||
|
ret_type = c.expr(last_stmt.expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c.rlocked_names = []
|
||||||
|
c.locked_names = []
|
||||||
if ret_type != ast.void_type {
|
if ret_type != ast.void_type {
|
||||||
node.is_expr = true
|
node.is_expr = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,13 @@ vlib/v/checker/tests/lock_already_locked.vv:11:3: error: nested `lock`/`rlock` n
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
12 | a.x++
|
12 | a.x++
|
||||||
13 | }
|
13 | }
|
||||||
|
vlib/v/checker/tests/lock_already_locked.vv:12:4: error: a has an `rlock` but needs a `lock`
|
||||||
|
10 | lock a {
|
||||||
|
11 | rlock a {
|
||||||
|
12 | a.x++
|
||||||
|
| ^
|
||||||
|
13 | }
|
||||||
|
14 | }
|
||||||
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
|
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
|
||||||
13 | }
|
13 | }
|
||||||
14 | }
|
14 | }
|
||||||
|
|
|
@ -456,6 +456,8 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
if val is ast.ArrayInit {
|
if val is ast.ArrayInit {
|
||||||
g.array_init(val, ident.name)
|
g.array_init(val, ident.name)
|
||||||
|
} else if val_type.has_flag(.shared_f) {
|
||||||
|
g.expr_with_cast(val, val_type, var_type)
|
||||||
} else {
|
} else {
|
||||||
g.expr(val)
|
g.expr(val)
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,8 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
||||||
g.write(' ? ')
|
g.write(' ? ')
|
||||||
}
|
}
|
||||||
prev_expected_cast_type := g.expected_cast_type
|
prev_expected_cast_type := g.expected_cast_type
|
||||||
if node.is_expr && g.table.sym(node.typ).kind == .sum_type {
|
if node.is_expr
|
||||||
|
&& (g.table.sym(node.typ).kind == .sum_type || node.typ.has_flag(.shared_f)) {
|
||||||
g.expected_cast_type = node.typ
|
g.expected_cast_type = node.typ
|
||||||
}
|
}
|
||||||
g.stmts(branch.stmts)
|
g.stmts(branch.stmts)
|
||||||
|
@ -204,7 +205,8 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
||||||
}
|
}
|
||||||
if needs_tmp_var {
|
if needs_tmp_var {
|
||||||
prev_expected_cast_type := g.expected_cast_type
|
prev_expected_cast_type := g.expected_cast_type
|
||||||
if node.is_expr && g.table.sym(node.typ).kind == .sum_type {
|
if node.is_expr
|
||||||
|
&& (g.table.sym(node.typ).kind == .sum_type || node.typ.has_flag(.shared_f)) {
|
||||||
g.expected_cast_type = node.typ
|
g.expected_cast_type = node.typ
|
||||||
}
|
}
|
||||||
g.stmts_with_tmp_var(branch.stmts, tmp)
|
g.stmts_with_tmp_var(branch.stmts, tmp)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
type AA = bool | int
|
||||||
|
|
||||||
|
fn test_shared_if_expr() {
|
||||||
|
shared a := [1, 2, 3]
|
||||||
|
b := [4, 5, 6]
|
||||||
|
c := lock a {
|
||||||
|
if a == b { a } else { b }
|
||||||
|
}
|
||||||
|
assert c == [4, 5, 6]
|
||||||
|
d := lock a {
|
||||||
|
if a != b {
|
||||||
|
a << 5
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert d == [1, 2, 3, 5]
|
||||||
|
}
|
Loading…
Reference in New Issue