Skip to content

Commit ba11067

Browse files
authored
parser: report a clear error for the if if cond { typo (fix #27907) (#27919)
1 parent 2641932 commit ba11067

3 files changed

Lines changed: 32 additions & 0 deletions

File tree

vlib/v/parser/if_match.v

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,17 @@ fn (mut p Parser) if_expr(is_comptime bool, is_expr bool) ast.IfExpr {
184184
p.comptime_if_cond = false
185185
}
186186
comments << p.eat_comments()
187+
// catch the common typo `if if cond {` / `} else if if cond {`, where a
188+
// second `if` was written by mistake. The inner `if` gets parsed as the
189+
// condition expression, so bail out with a helpful message instead of the
190+
// confusing `expecting {` error that appears further down the file.
191+
if !is_comptime && p.tok.kind != .lcbr {
192+
if cond is ast.IfExpr && !cond.has_else {
193+
p.error_with_pos('the condition of an `if` should be a boolean expression, not another `if` statement; did you write `if` twice by mistake?',
194+
cond.pos)
195+
return ast.IfExpr{}
196+
}
197+
}
187198
end_pos := p.prev_tok.pos()
188199
body_pos := p.tok.pos()
189200
p.inside_if = false
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/parser/tests/if_double_if_cond_err.vv:6:12: error: the condition of an `if` should be a boolean expression, not another `if` statement; did you write `if` twice by mistake?
2+
4 | if x == 1 {
3+
5 | commands << 'a'
4+
6 | } else if if x == 2 {
5+
| ~~
6+
7 | commands << 'b'
7+
8 | }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fn get_commands() []string {
2+
mut commands := []string{}
3+
x := 1
4+
if x == 1 {
5+
commands << 'a'
6+
} else if if x == 2 {
7+
commands << 'b'
8+
}
9+
return commands
10+
}
11+
12+
fn main() {
13+
println(get_commands())
14+
}

0 commit comments

Comments
 (0)