Skip to content

Commit f4d3c7e

Browse files
authored
parser,checker: improve the position underlining, for last statements in branches of if expressions (#22845)
1 parent 8ebbace commit f4d3c7e

6 files changed

Lines changed: 29 additions & 8 deletions

File tree

vlib/v/checker/if.v

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
3232
stmts := node.branches[0].stmts
3333
if stmts.len > 0 && stmts.last() is ast.ExprStmt && stmts.last().typ != ast.void_type {
3434
node_is_expr = true
35+
} else if node.is_expr {
36+
node_is_expr = true
3537
}
3638
}
3739
if c.expected_type == ast.void_type && node_is_expr {
@@ -520,8 +522,9 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
520522
}
521523
}
522524
} else if !node.is_comptime && stmt !in [ast.Return, ast.BranchStmt] {
525+
pos := if node_is_expr { stmt.pos } else { branch.pos }
523526
c.error('`${if_kind}` expression requires an expression as the last statement of every branch',
524-
branch.pos)
527+
pos)
525528
}
526529
} else if !node.is_comptime {
527530
c.error('`${if_kind}` expression requires an expression as the last statement of every branch',
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/checker/tests/if_expr_last_branch_stmt_err.vv:5:30: error: `if` expression requires an expression as the last statement of every branch
2+
3 | mut start := 0
3+
4 |
4+
5 | start = if val < 20 { start += 1 } else { start }
5+
| ~~
6+
6 | dump(start)
7+
7 | }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
val := 15
3+
mut start := 0
4+
5+
start = if val < 20 { start += 1 } else { start }
6+
dump(start)
7+
}

vlib/v/parser/expr.v

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr {
128128
p.is_stmt_ident = is_stmt_ident
129129
}
130130
.key_if {
131-
return p.if_expr(true)
131+
return p.if_expr(true, false)
132132
}
133133
else {
134134
return p.unexpected_with_pos(p.peek_tok.pos(),
@@ -222,7 +222,11 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr {
222222
if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) {
223223
node = p.call_expr(p.language, p.mod)
224224
} else {
225-
node = p.if_expr(false)
225+
mut is_expr := false
226+
if p.prev_tok.kind.is_assign() {
227+
is_expr = true
228+
}
229+
node = p.if_expr(false, is_expr)
226230
}
227231
}
228232
.key_unsafe {

vlib/v/parser/if_match.v

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ module parser
66
import v.ast
77
import v.token
88

9-
fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
9+
fn (mut p Parser) if_expr(is_comptime bool, is_expr bool) ast.IfExpr {
1010
was_inside_if_expr := p.inside_if_expr
1111
was_inside_ct_if_expr := p.inside_ct_if_expr
1212
defer {
1313
p.inside_if_expr = was_inside_if_expr
1414
p.inside_ct_if_expr = was_inside_ct_if_expr
1515
}
1616
p.inside_if_expr = true
17-
is_expr := p.prev_tok.kind == .key_return
17+
is_expr_ := p.prev_tok.kind == .key_return || is_expr
1818
mut pos := p.tok.pos()
1919
if is_comptime {
2020
p.inside_ct_if_expr = true
@@ -213,7 +213,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
213213
post_comments: comments
214214
pos: pos
215215
has_else: has_else
216-
is_expr: is_expr
216+
is_expr: is_expr_
217217
}
218218
}
219219

vlib/v/parser/parser.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ fn (mut p Parser) top_stmt() ast.Stmt {
795795
comptime_for_stmt := p.comptime_for()
796796
return p.other_stmts(comptime_for_stmt)
797797
} else if p.peek_tok.kind == .key_if {
798-
if_expr := p.if_expr(true)
798+
if_expr := p.if_expr(true, false)
799799
cur_stmt := ast.ExprStmt{
800800
expr: if_expr
801801
pos: if_expr.pos
@@ -1077,7 +1077,7 @@ fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
10771077
match p.peek_tok.kind {
10781078
.key_if {
10791079
mut pos := p.tok.pos()
1080-
expr := p.if_expr(true)
1080+
expr := p.if_expr(true, false)
10811081
pos.update_last_line(p.prev_tok.line_nr)
10821082
return ast.ExprStmt{
10831083
expr: expr

0 commit comments

Comments
 (0)