Skip to content

Commit 13efcad

Browse files
authored
parser,checker: smart detect or {} inside loop when using c <-val (fix #24550) (#25435)
1 parent a72af10 commit 13efcad

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

vlib/v/checker/checker.v

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,6 +2339,14 @@ fn (mut c Checker) stmt(mut node ast.Stmt) {
23392339
c.error('unused expression', node.pos)
23402340
}
23412341
}
2342+
if node.expr.op == .arrow {
2343+
if mut node.expr.right is ast.CallExpr {
2344+
if node.expr.right.return_type.has_flag(.result) {
2345+
node.expr.or_block.err_used = node.expr.or_block.scope.known_var('err')
2346+
node.expr.right.or_block = node.expr.or_block
2347+
}
2348+
}
2349+
}
23422350
}
23432351
}
23442352
if !c.inside_return {

vlib/v/parser/expr.v

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,17 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
827827
mut or_scope := &ast.Scope(unsafe { nil })
828828
// allow `x := <-ch or {...}` to handle closed channel
829829
if op == .arrow {
830+
if mut right is ast.SelectorExpr {
831+
or_kind = right.or_block.kind
832+
or_stmts = right.or_block.stmts.clone()
833+
right.or_block = ast.OrExpr{}
834+
}
835+
if mut right is ast.CallExpr {
836+
or_kind = right.or_block.kind
837+
or_stmts = right.or_block.stmts.clone()
838+
or_scope = right.or_block.scope
839+
right.or_block = ast.OrExpr{}
840+
}
830841
if p.tok.kind == .key_orelse {
831842
or_kind = .block
832843
or_stmts, or_pos, or_scope = p.or_block(.with_err_var)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[vlib/v/slow_tests/inout/for_channel_or_expr_block.vv:22] a.any(it in [i64(1), 2, 3, 4, 5, 6, 7]): true
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import time
2+
3+
fn writer(c chan i64, delay i64) {
4+
for {
5+
time.sleep(delay)
6+
7+
c <- time.now().day_of_week() or {
8+
break
9+
}
10+
}
11+
}
12+
13+
fn reader(c chan i64, max int) {
14+
mut a := []i64{}
15+
for {
16+
a << <-c
17+
if a.len > max {
18+
c.close()
19+
break
20+
}
21+
}
22+
dump(a.any(it in [i64(1), 2, 3, 4, 5, 6, 7]))
23+
}
24+
25+
fn main() {
26+
c := chan i64{}
27+
mut t := []thread{}
28+
t << spawn reader(c, 0)
29+
t << spawn writer(c, 10 * time.millisecond)
30+
t.wait()
31+
}

0 commit comments

Comments
 (0)