From 1e5627e777b8adb2045e8c283f4794aed2c0e19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Fri, 23 Jul 2021 22:24:27 +0200 Subject: [PATCH] parser: don't require unary `>` prefix for `select` timeout (#10928) --- cmd/tools/vwatch.v | 2 +- doc/docs.md | 2 +- vlib/context/README.md | 4 +- vlib/context/deadline_test.v | 4 +- vlib/sync/channel_select_3_test.v | 2 +- vlib/v/checker/checker.v | 2 +- vlib/v/fmt/fmt.v | 3 -- vlib/v/fmt/tests/select_keep.vv | 2 +- vlib/v/parser/if_match.v | 59 ++++++++++++------------ vlib/v/parser/tests/select_bad_key_1.out | 7 +++ vlib/v/parser/tests/select_bad_key_2.out | 4 +- vlib/v/parser/tests/select_bad_key_2.vv | 2 +- vlib/v/parser/tests/select_bad_key_3.out | 12 ++--- vlib/v/parser/tests/select_bad_key_3.vv | 1 - vlib/v/parser/tests/select_else_1.out | 6 +-- vlib/v/parser/tests/select_else_1.vv | 2 +- vlib/v/parser/tests/select_else_2.out | 7 +++ 17 files changed, 65 insertions(+), 56 deletions(-) diff --git a/cmd/tools/vwatch.v b/cmd/tools/vwatch.v index 64ad444355..0ac243d7ab 100644 --- a/cmd/tools/vwatch.v +++ b/cmd/tools/vwatch.v @@ -270,7 +270,7 @@ fn (mut context Context) compilation_runner_loop() { return } } - > 100 * time.millisecond { + 100 * time.millisecond { should_restart := RerunCommand.restart in cmds cmds = [] if should_restart { diff --git a/doc/docs.md b/doc/docs.md index d84613dbf4..bae2078658 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -3350,7 +3350,7 @@ fn main() { time.sleep(5 * time.millisecond) eprintln('> c: $c was send on channel ch3') } - > 500 * time.millisecond { + 500 * time.millisecond { // do something if no channel has become ready within 0.5s eprintln('> more than 0.5s passed without a channel being ready') } diff --git a/vlib/context/README.md b/vlib/context/README.md index 4743a97f14..7fbf18b752 100644 --- a/vlib/context/README.md +++ b/vlib/context/README.md @@ -99,7 +99,7 @@ fn example_with_deadline() { ctx_ch := ctx.done() select { _ := <-ctx_ch {} - > 1 * time.second { + 1 * time.second { panic('This should not happen') } } @@ -130,7 +130,7 @@ fn example_with_timeout() { ctx_ch := ctx.done() select { _ := <-ctx_ch {} - > 1 * time.second { + 1 * time.second { panic('This should not happen') } } diff --git a/vlib/context/deadline_test.v b/vlib/context/deadline_test.v index 2d6a939923..e4d7280d7c 100644 --- a/vlib/context/deadline_test.v +++ b/vlib/context/deadline_test.v @@ -22,7 +22,7 @@ fn test_with_deadline() { ctx_ch := ctx.done() select { _ := <-ctx_ch {} - > 1 * time.second { + 1 * time.second { panic('This should not happen') } } @@ -41,7 +41,7 @@ fn test_with_timeout() { ctx_ch := ctx.done() select { _ := <-ctx_ch {} - > 1 * time.second { + 1 * time.second { panic('This should not happen') } } diff --git a/vlib/sync/channel_select_3_test.v b/vlib/sync/channel_select_3_test.v index 9954ee3afe..fdf609659d 100644 --- a/vlib/sync/channel_select_3_test.v +++ b/vlib/sync/channel_select_3_test.v @@ -32,7 +32,7 @@ fn f1(ch1 chan int, ch2 chan St, ch3 chan int, ch4 chan int, ch5 chan int, mut s ch5 <- getint() { a = 9 } - > 300 * time.millisecond { + 300 * time.millisecond { a = 3 } } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8d86f2dc82..00d3ed59e0 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -6330,7 +6330,7 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type { if branch.is_timeout { if !branch.stmt.typ.is_int() { tsym := c.table.get_type_symbol(branch.stmt.typ) - c.error('invalid type `$tsym.name` for timeout - expected integer type aka `time.Duration`', + c.error('invalid type `$tsym.name` for timeout - expected integer number of nanoseconds aka `time.Duration`', branch.stmt.pos) } } else { diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 8db0a8d9be..dd77b82d6d 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -2169,9 +2169,6 @@ pub fn (mut f Fmt) select_expr(node ast.SelectExpr) { if branch.is_else { f.write('else {') } else { - if branch.is_timeout { - f.write('> ') - } f.single_line_if = true match branch.stmt { ast.ExprStmt { f.expr(branch.stmt.expr) } diff --git a/vlib/v/fmt/tests/select_keep.vv b/vlib/v/fmt/tests/select_keep.vv index afc27c3d6f..4a5abf77f0 100644 --- a/vlib/v/fmt/tests/select_keep.vv +++ b/vlib/v/fmt/tests/select_keep.vv @@ -34,7 +34,7 @@ fn f1(ch1 chan int, ch2 chan St, ch3 chan int, ch4 chan int, ch5 chan int, sem s ch5 <- getint() { a = 9 } - > 300 * time.millisecond { + 300 * time.millisecond { a = 3 } // post comment diff --git a/vlib/v/parser/if_match.v b/vlib/v/parser/if_match.v index f1e0fe9893..99df1811cf 100644 --- a/vlib/v/parser/if_match.v +++ b/vlib/v/parser/if_match.v @@ -309,30 +309,14 @@ fn (mut p Parser) select_expr() ast.SelectExpr { is_else = true has_else = true p.next() - } else if p.tok.kind == .gt { - if has_else { - p.error_with_pos('`else` and timeout `> t` are mutually exclusive `select` keys', - p.tok.position()) - return ast.SelectExpr{} - } - if has_timeout { - p.error_with_pos('at most one timeout `> t` branch allowed in `select` block', - p.tok.position()) - return ast.SelectExpr{} - } - is_timeout = true - has_timeout = true - p.next() - p.inside_match = true - expr := p.expr(0) - p.inside_match = false - stmt = ast.ExprStmt{ - expr: expr - pos: expr.position() - comments: [comment] - is_expr: true - } } else { + mut is_gt := false + if p.tok.kind == .gt { + is_gt = true + p.note_with_pos('`>` is deprecated and will soon be forbidden - just state the timeout in nanoseconds', + p.tok.position()) + p.next() + } p.inside_match = true p.inside_select = true exprs, comments := p.expr_list() @@ -354,6 +338,7 @@ fn (mut p Parser) select_expr() ast.SelectExpr { p.inside_select = false match mut stmt { ast.ExprStmt { + mut check_timeout := false if !stmt.is_expr { p.error_with_pos('select: invalid expression', stmt.pos) return ast.SelectExpr{} @@ -361,18 +346,31 @@ fn (mut p Parser) select_expr() ast.SelectExpr { match mut stmt.expr { ast.InfixExpr { if stmt.expr.op != .arrow { - p.error_with_pos('select key: `<-` operator expected', - stmt.expr.pos) - return ast.SelectExpr{} + check_timeout = true + } else if is_gt { + p.error_with_pos('send expression cannot be used as timeout', + stmt.pos) } } else { - p.error_with_pos('select key: send expression (`ch <- x`) expected', - stmt.pos) - return ast.SelectExpr{} + check_timeout = true } } } + if check_timeout { + if has_else { + p.error_with_pos('`else` and timeout value are mutually exclusive `select` keys', + stmt.pos) + return ast.SelectExpr{} + } + if has_timeout { + p.error_with_pos('at most one timeout branch allowed in `select` block', + stmt.pos) + return ast.SelectExpr{} + } + is_timeout = true + has_timeout = true + } } ast.AssignStmt { expr := stmt.right[0] @@ -392,7 +390,8 @@ fn (mut p Parser) select_expr() ast.SelectExpr { } } else { - p.error_with_pos('select: transmission statement expected', stmt.pos) + p.error_with_pos('select: transmission statement, timeout (in ns) or `else` expected', + stmt.pos) return ast.SelectExpr{} } } diff --git a/vlib/v/parser/tests/select_bad_key_1.out b/vlib/v/parser/tests/select_bad_key_1.out index 6484827c10..a9f946ca4f 100644 --- a/vlib/v/parser/tests/select_bad_key_1.out +++ b/vlib/v/parser/tests/select_bad_key_1.out @@ -1,3 +1,10 @@ +vlib/v/parser/tests/select_bad_key_1.vv:19:3: notice: `>` is deprecated and will soon be forbidden - just state the timeout in nanoseconds + 17 | a++ + 18 | } + 19 | > 50 * time.millisecond { + | ^ + 20 | println('timeout') + 21 | } vlib/v/parser/tests/select_bad_key_1.vv:39:8: error: select key: receive expression expected 37 | fn f3_bad(ch1 chan St) { 38 | select { diff --git a/vlib/v/parser/tests/select_bad_key_2.out b/vlib/v/parser/tests/select_bad_key_2.out index 9cb2d06983..a7a61093ad 100644 --- a/vlib/v/parser/tests/select_bad_key_2.out +++ b/vlib/v/parser/tests/select_bad_key_2.out @@ -1,7 +1,7 @@ -vlib/v/parser/tests/select_bad_key_2.vv:7:5: error: select key: `<-` operator expected +vlib/v/parser/tests/select_bad_key_2.vv:7:3: error: invalid type `f64` for timeout - expected integer number of nanoseconds aka `time.Duration` 5 | println(b) 6 | } 7 | a + 7 { - | ^ + | ~~~~~ 8 | println("shouldn't get here") 9 | } diff --git a/vlib/v/parser/tests/select_bad_key_2.vv b/vlib/v/parser/tests/select_bad_key_2.vv index 52593814c3..a3fcda8f11 100644 --- a/vlib/v/parser/tests/select_bad_key_2.vv +++ b/vlib/v/parser/tests/select_bad_key_2.vv @@ -1,5 +1,5 @@ fn f3_bad(ch1 chan int) { - a := 5 + a := 3.75 select { b := <-ch1 { println(b) diff --git a/vlib/v/parser/tests/select_bad_key_3.out b/vlib/v/parser/tests/select_bad_key_3.out index 41fc51522c..029add664e 100644 --- a/vlib/v/parser/tests/select_bad_key_3.out +++ b/vlib/v/parser/tests/select_bad_key_3.out @@ -1,7 +1,7 @@ -vlib/v/parser/tests/select_bad_key_3.vv:7:3: error: select key: send expression (`ch <- x`) expected - 5 | println(b) - 6 | } - 7 | println(7) { +vlib/v/parser/tests/select_bad_key_3.vv:6:3: error: invalid type `void` for timeout - expected integer number of nanoseconds aka `time.Duration` + 4 | println(b) + 5 | } + 6 | println(7) { | ~~~~~~~~~~ - 8 | println("shouldn't get here") - 9 | } + 7 | println("shouldn't get here") + 8 | } diff --git a/vlib/v/parser/tests/select_bad_key_3.vv b/vlib/v/parser/tests/select_bad_key_3.vv index 82533dda53..c7bf3a6f3e 100644 --- a/vlib/v/parser/tests/select_bad_key_3.vv +++ b/vlib/v/parser/tests/select_bad_key_3.vv @@ -1,5 +1,4 @@ fn f3_bad(ch1 chan int) { - a := 5 select { b := <-ch1 { println(b) diff --git a/vlib/v/parser/tests/select_else_1.out b/vlib/v/parser/tests/select_else_1.out index 9f74c528d0..9704fbb8ca 100644 --- a/vlib/v/parser/tests/select_else_1.out +++ b/vlib/v/parser/tests/select_else_1.out @@ -1,7 +1,7 @@ -vlib/v/parser/tests/select_else_1.vv:12:3: error: `else` and timeout `> t` are mutually exclusive `select` keys +vlib/v/parser/tests/select_else_1.vv:12:3: error: `else` and timeout value are mutually exclusive `select` keys 10 | println("shouldn't get here") 11 | } - 12 | > 30 * time.millisecond { - | ^ + 12 | 30 * time.millisecond { + | ~~~~~~~~~~~~~~~~~~~~~ 13 | println('bad') 14 | } diff --git a/vlib/v/parser/tests/select_else_1.vv b/vlib/v/parser/tests/select_else_1.vv index 8c8c7a1001..78077f481a 100644 --- a/vlib/v/parser/tests/select_else_1.vv +++ b/vlib/v/parser/tests/select_else_1.vv @@ -9,7 +9,7 @@ fn f3_bad(ch1 chan int) { else { println("shouldn't get here") } - > 30 * time.millisecond { + 30 * time.millisecond { println('bad') } } diff --git a/vlib/v/parser/tests/select_else_2.out b/vlib/v/parser/tests/select_else_2.out index afe53de4c4..f927031360 100644 --- a/vlib/v/parser/tests/select_else_2.out +++ b/vlib/v/parser/tests/select_else_2.out @@ -1,3 +1,10 @@ +vlib/v/parser/tests/select_else_2.vv:9:3: notice: `>` is deprecated and will soon be forbidden - just state the timeout in nanoseconds + 7 | println(b) + 8 | } + 9 | > 30 * time.millisecond { + | ^ + 10 | println('bad') + 11 | } vlib/v/parser/tests/select_else_2.vv:12:3: error: timeout `> t` and `else` are mutually exclusive `select` keys 10 | println('bad') 11 | }