1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: fix channel pop with or expression: ch := <-self.item or { return none } (#17392)

This commit is contained in:
yuyi 2023-02-23 22:45:15 +08:00 committed by GitHub
parent 248e9538ca
commit acd903484d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 3 deletions

View File

@ -711,11 +711,14 @@ fn (mut p Parser) prefix_expr() ast.Expr {
mut or_pos := p.tok.pos()
// allow `x := <-ch or {...}` to handle closed channel
if op == .arrow {
if p.tok.kind == .key_orelse {
if mut right is ast.SelectorExpr {
or_kind = right.or_block.kind
or_stmts = right.or_block.stmts.clone()
right.or_block = ast.OrExpr{}
} else if p.tok.kind == .key_orelse {
or_kind = .block
or_stmts, or_pos = p.or_block(.with_err_var)
}
if p.tok.kind == .question {
} else if p.tok.kind == .question {
p.next()
or_kind = .propagate_option
}

View File

@ -45,3 +45,30 @@ fn test_chan_of_sumtype() {
println(ret)
assert '${ret}' == 'As(Aa{})'
}
struct Iter[T] {
item chan T
}
fn new_iter[T](ch chan T) Iter[T] {
return Iter[T]{
item: ch
}
}
fn (self Iter[T]) next() ?T {
self.item.close()
ch := <-self.item or { return none }
return ch
}
fn test_channel_with_or_block() {
ch := chan int{}
iter := new_iter[int](ch)
ret := iter.next() or {
assert true
return
}
println(ret)
assert false
}