parser: fix optional with multiple statements (#14592)

master
yuyi 2022-06-02 13:23:16 +08:00 committed by GitHub
parent 5bf246fce6
commit 10fb16e00b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 67 deletions

View File

@ -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')
}

View File

@ -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 {`

View File

@ -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 | }

View File

@ -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
}
}

View File

@ -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')
}