From acd903484d8eb45664d353cd4bcbfec7d155fef6 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 23 Feb 2023 22:45:15 +0800 Subject: [PATCH] parser: fix channel pop with or expression: `ch := <-self.item or { return none }` (#17392) --- vlib/v/parser/expr.v | 9 ++++++--- vlib/v/tests/channels_test.v | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index dbf084f5ba..9b53b40c95 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -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 } diff --git a/vlib/v/tests/channels_test.v b/vlib/v/tests/channels_test.v index 4097f6e216..041c93f627 100644 --- a/vlib/v/tests/channels_test.v +++ b/vlib/v/tests/channels_test.v @@ -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 +}