From 10fb16e00b487fc2b700d45a52e89ca5b0e356fc Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 2 Jun 2022 13:23:16 +0800 Subject: [PATCH] parser: fix optional with multiple statements (#14592) --- .../tests/optional_with_multi_stmts_keep.vv | 12 ++++++++ vlib/v/parser/expr.v | 12 ++------ vlib/v/parser/tests/prefix_first.out | 28 ------------------ vlib/v/parser/tests/prefix_first.vv | 29 ------------------- vlib/v/tests/or_expr_with_multi_stmts_test.v | 12 ++++++++ 5 files changed, 26 insertions(+), 67 deletions(-) create mode 100644 vlib/v/fmt/tests/optional_with_multi_stmts_keep.vv delete mode 100644 vlib/v/parser/tests/prefix_first.out delete mode 100644 vlib/v/parser/tests/prefix_first.vv create mode 100644 vlib/v/tests/or_expr_with_multi_stmts_test.v diff --git a/vlib/v/fmt/tests/optional_with_multi_stmts_keep.vv b/vlib/v/fmt/tests/optional_with_multi_stmts_keep.vv new file mode 100644 index 0000000000..87481384af --- /dev/null +++ b/vlib/v/fmt/tests/optional_with_multi_stmts_keep.vv @@ -0,0 +1,12 @@ +fn main() { + x := fmt_test() or { + println(err.msg()) + -100 + } + println(x) + assert x == -100 +} + +fn fmt_test() ?int { + return error('foo') +} diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index 2e5f5c3dab..dd6e9c9afe 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -443,16 +443,8 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden pos: pos is_stmt: true } - } else if p.tok.kind.is_infix() { - if p.tok.kind.is_prefix() && p.tok.line_nr != p.prev_tok.line_nr { - // return early for deref assign `*x = 2` goes to prefix expr - if p.tok.kind == .mul && p.peek_token(2).kind == .assign { - return node - } - // added 10/2020: LATER this will be parsed as PrefixExpr instead - p.warn_with_pos('move infix `$p.tok.kind` operator before new line (if infix intended) or use brackets for a prefix expression', - p.tok.pos()) - } + } else if p.tok.kind.is_infix() && !(p.tok.kind in [.minus, .amp, .mul] + && p.tok.line_nr != p.prev_tok.line_nr) { // continue on infix expr node = p.infix_expr(node) // return early `if bar is SumType as b {` diff --git a/vlib/v/parser/tests/prefix_first.out b/vlib/v/parser/tests/prefix_first.out deleted file mode 100644 index d723fa55d6..0000000000 --- a/vlib/v/parser/tests/prefix_first.out +++ /dev/null @@ -1,28 +0,0 @@ -vlib/v/parser/tests/prefix_first.vv:15:3: warning: move infix `-` operator before new line (if infix intended) or use brackets for a prefix expression - 13 | _ = if true { - 14 | v = 1 - 15 | -1 - | ^ - 16 | } else {1} - 17 | _ = p -vlib/v/parser/tests/prefix_first.vv:27:3: warning: move infix `&` operator before new line (if infix intended) or use brackets for a prefix expression - 25 | _ = opt() or { - 26 | _ = 1 - 27 | &v - | ^ - 28 | } - 29 | } -vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch - 11 | - 12 | // later this should compile correctly - 13 | _ = if true { - | ~~~~~~~ - 14 | v = 1 - 15 | -1 -vlib/v/parser/tests/prefix_first.vv:26:5: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope - 24 | v := 3 - 25 | _ = opt() or { - 26 | _ = 1 - | ^ - 27 | &v - 28 | } diff --git a/vlib/v/parser/tests/prefix_first.vv b/vlib/v/parser/tests/prefix_first.vv deleted file mode 100644 index 83e180c29a..0000000000 --- a/vlib/v/parser/tests/prefix_first.vv +++ /dev/null @@ -1,29 +0,0 @@ -// a prefix op can be parsed as an infix op if there's an expression on the line before -// https://github.com/vlang/v/pull/6491 -fn test_prefix() { - mut v := 1 - mut p := &v - // OK, special workaround - unsafe { - v = 1 - *p = 2 - } - - // later this should compile correctly - _ = if true { - v = 1 - -1 - } else {1} - _ = p -} - -fn opt() ?&int {return none} - -fn test_prefix_or() { - // later this should compile correctly - v := 3 - _ = opt() or { - _ = 1 - &v - } -} diff --git a/vlib/v/tests/or_expr_with_multi_stmts_test.v b/vlib/v/tests/or_expr_with_multi_stmts_test.v new file mode 100644 index 0000000000..7eea61bd4e --- /dev/null +++ b/vlib/v/tests/or_expr_with_multi_stmts_test.v @@ -0,0 +1,12 @@ +fn test_or_expr_with_multi_stmts() { + x := fmt_test() or { + println(err.msg()) + -100 + } + println(x) + assert x == -100 +} + +fn fmt_test() ?int { + return error('foo') +}