parser: fixes or block position (#6736)
parent
fff70368b7
commit
a2fc19880a
|
@ -1618,10 +1618,10 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t
|
||||||
return ret_type
|
return ret_type
|
||||||
} else if expr.or_block.kind == .block {
|
} else if expr.or_block.kind == .block {
|
||||||
c.error('unexpected `or` block, the function `$expr.name` does not return an optional',
|
c.error('unexpected `or` block, the function `$expr.name` does not return an optional',
|
||||||
expr.pos)
|
expr.or_block.pos)
|
||||||
} else if expr.or_block.kind == .propagate {
|
} else if expr.or_block.kind == .propagate {
|
||||||
c.error('unexpected `?`, the function `$expr.name`, does not return an optional',
|
c.error('unexpected `?`, the function `$expr.name`, does not return an optional',
|
||||||
expr.pos)
|
expr.or_block.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret_type
|
return ret_type
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
vlib/v/checker/tests/or_err.vv:4:6: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
|
vlib/v/checker/tests/or_err.vv:4:10: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
|
||||||
2 | return none
|
2 | return none
|
||||||
3 | }
|
3 | }
|
||||||
4 | a := f() or {
|
4 | a := f() or {
|
||||||
| ~~~
|
| ~~~~
|
||||||
5 | {}
|
5 | {}
|
||||||
6 | }
|
6 | }
|
||||||
vlib/v/checker/tests/or_err.vv:11:2: error: wrong return type `rune` in the `or {}` block, expected `&int`
|
vlib/v/checker/tests/or_err.vv:11:2: error: wrong return type `rune` in the `or {}` block, expected `&int`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
vlib/v/checker/tests/unexpected_or.vv:6:6: error: unexpected `or` block, the function `ret_zero` does not return an optional
|
vlib/v/checker/tests/unexpected_or.vv:6:17: error: unexpected `or` block, the function `ret_zero` does not return an optional
|
||||||
4 |
|
4 |
|
||||||
5 | fn main() {
|
5 | fn main() {
|
||||||
6 | _ = ret_zero() or { 1 }
|
6 | _ = ret_zero() or { 1 }
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~
|
||||||
7 | }
|
7 | }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
vlib/v/checker/tests/unexpected_or_propagate.vv:6:7: error: unexpected `?`, the function `ret_zero`, does not return an optional
|
vlib/v/checker/tests/unexpected_or_propagate.vv:6:17: error: unexpected `?`, the function `ret_zero`, does not return an optional
|
||||||
4 |
|
4 |
|
||||||
5 | fn opt_fn() ?int {
|
5 | fn opt_fn() ?int {
|
||||||
6 | a := ret_zero()?
|
6 | a := ret_zero()?
|
||||||
| ~~~~~~~~~~
|
| ^
|
||||||
7 | return a
|
7 | return a
|
||||||
8 | }
|
8 | }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
vlib/v/checker/tests/wrong_propagate_ret_type.vv:6:7: error: to propagate the optional call, `opt_call` must itself return an optional
|
vlib/v/checker/tests/wrong_propagate_ret_type.vv:6:17: error: to propagate the optional call, `opt_call` must itself return an optional
|
||||||
4 |
|
4 |
|
||||||
5 | fn opt_call() int {
|
5 | fn opt_call() int {
|
||||||
6 | a := ret_none()?
|
6 | a := ret_none()?
|
||||||
| ~~~~~~~~~~
|
| ^
|
||||||
7 | return a
|
7 | return a
|
||||||
8 | }
|
8 | }
|
||||||
|
|
|
@ -54,6 +54,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
||||||
len: last_pos.pos - first_pos.pos + last_pos.len
|
len: last_pos.pos - first_pos.pos + last_pos.len
|
||||||
}
|
}
|
||||||
mut or_stmts := []ast.Stmt{}
|
mut or_stmts := []ast.Stmt{}
|
||||||
|
mut or_pos := p.tok.position()
|
||||||
if p.tok.kind == .key_orelse {
|
if p.tok.kind == .key_orelse {
|
||||||
// `foo() or {}``
|
// `foo() or {}``
|
||||||
was_inside_or_expr := p.inside_or_expr
|
was_inside_or_expr := p.inside_or_expr
|
||||||
|
@ -74,6 +75,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
||||||
})
|
})
|
||||||
or_kind = .block
|
or_kind = .block
|
||||||
or_stmts = p.parse_block_no_scope(false)
|
or_stmts = p.parse_block_no_scope(false)
|
||||||
|
or_pos = or_pos.extend(p.prev_tok.position())
|
||||||
p.close_scope()
|
p.close_scope()
|
||||||
p.inside_or_expr = was_inside_or_expr
|
p.inside_or_expr = was_inside_or_expr
|
||||||
}
|
}
|
||||||
|
@ -89,37 +91,18 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
||||||
fn_name = registered.name
|
fn_name = registered.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
call_expr := ast.CallExpr{
|
|
||||||
name: fn_name
|
|
||||||
args: args
|
|
||||||
mod: fn_mod
|
|
||||||
pos: pos
|
|
||||||
language: language
|
|
||||||
generic_type: generic_type
|
|
||||||
}
|
|
||||||
if or_kind != .absent {
|
|
||||||
return ast.OrExpr2{
|
|
||||||
call_expr: call_expr
|
|
||||||
stmts: or_stmts
|
|
||||||
kind: or_kind
|
|
||||||
pos: pos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return call_expr
|
|
||||||
*/
|
|
||||||
return ast.CallExpr{
|
return ast.CallExpr{
|
||||||
name: fn_name
|
name: fn_name
|
||||||
args: args
|
args: args
|
||||||
mod: fn_mod
|
mod: fn_mod
|
||||||
pos: pos
|
pos: pos
|
||||||
language: language
|
language: language
|
||||||
|
generic_type: generic_type
|
||||||
or_block: ast.OrExpr{
|
or_block: ast.OrExpr{
|
||||||
stmts: or_stmts
|
stmts: or_stmts
|
||||||
kind: or_kind
|
kind: or_kind
|
||||||
pos: pos
|
pos: or_pos
|
||||||
}
|
}
|
||||||
generic_type: generic_type
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1238,6 +1238,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
||||||
p.check(.rpar)
|
p.check(.rpar)
|
||||||
mut or_stmts := []ast.Stmt{}
|
mut or_stmts := []ast.Stmt{}
|
||||||
mut or_kind := ast.OrKind.absent
|
mut or_kind := ast.OrKind.absent
|
||||||
|
mut or_pos := p.tok.position()
|
||||||
if p.tok.kind == .key_orelse {
|
if p.tok.kind == .key_orelse {
|
||||||
p.next()
|
p.next()
|
||||||
p.open_scope()
|
p.open_scope()
|
||||||
|
@ -1255,6 +1256,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
||||||
})
|
})
|
||||||
or_kind = .block
|
or_kind = .block
|
||||||
or_stmts = p.parse_block_no_scope(false)
|
or_stmts = p.parse_block_no_scope(false)
|
||||||
|
or_pos = or_pos.extend(p.prev_tok.position())
|
||||||
p.close_scope()
|
p.close_scope()
|
||||||
}
|
}
|
||||||
// `foo()?`
|
// `foo()?`
|
||||||
|
@ -1278,7 +1280,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
||||||
or_block: ast.OrExpr{
|
or_block: ast.OrExpr{
|
||||||
stmts: or_stmts
|
stmts: or_stmts
|
||||||
kind: or_kind
|
kind: or_kind
|
||||||
pos: pos
|
pos: or_pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if is_filter || field_name == 'sort' {
|
if is_filter || field_name == 'sort' {
|
||||||
|
|
|
@ -355,6 +355,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
|
||||||
}
|
}
|
||||||
mut or_stmts := []ast.Stmt{}
|
mut or_stmts := []ast.Stmt{}
|
||||||
mut or_kind := ast.OrKind.absent
|
mut or_kind := ast.OrKind.absent
|
||||||
|
mut or_pos := p.tok.position()
|
||||||
// allow `x := <-ch or {...}` to handle closed channel
|
// allow `x := <-ch or {...}` to handle closed channel
|
||||||
if op == .arrow {
|
if op == .arrow {
|
||||||
if p.tok.kind == .key_orelse {
|
if p.tok.kind == .key_orelse {
|
||||||
|
@ -374,6 +375,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
|
||||||
})
|
})
|
||||||
or_kind = .block
|
or_kind = .block
|
||||||
or_stmts = p.parse_block_no_scope(false)
|
or_stmts = p.parse_block_no_scope(false)
|
||||||
|
or_pos = or_pos.extend(p.prev_tok.position())
|
||||||
p.close_scope()
|
p.close_scope()
|
||||||
}
|
}
|
||||||
if p.tok.kind == .question {
|
if p.tok.kind == .question {
|
||||||
|
@ -388,7 +390,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
|
||||||
or_block: ast.OrExpr{
|
or_block: ast.OrExpr{
|
||||||
stmts: or_stmts
|
stmts: or_stmts
|
||||||
kind: or_kind
|
kind: or_kind
|
||||||
pos: pos
|
pos: or_pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@ vlib/v/parser/tests/prefix_first.vv:26:3: warning: move infix `&` operator befor
|
||||||
27 | }
|
27 | }
|
||||||
28 | }
|
28 | }
|
||||||
vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch
|
vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch
|
||||||
11 |
|
11 |
|
||||||
12 | // later this should compile correctly
|
12 | // later this should compile correctly
|
||||||
13 | _ = if true {
|
13 | _ = if true {
|
||||||
| ~~~~~~~
|
| ~~~~~~~
|
||||||
14 | v = 1
|
14 | v = 1
|
||||||
15 | -1
|
15 | -1
|
||||||
vlib/v/parser/tests/prefix_first.vv:24:6: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
|
vlib/v/parser/tests/prefix_first.vv:24:12: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
|
||||||
22 | // later this should compile correctly
|
22 | // later this should compile correctly
|
||||||
23 | v := 3
|
23 | v := 3
|
||||||
24 | _ = opt() or {
|
24 | _ = opt() or {
|
||||||
| ~~~~~
|
| ~~~~
|
||||||
25 | _ = 1
|
25 | _ = 1
|
||||||
26 | &v
|
26 | &v
|
||||||
|
|
Loading…
Reference in New Issue