checker: fix missing check on range expr when high var is same iteration value var (#23130)

This commit is contained in:
Felipe Pena 2024-12-11 09:31:31 -03:00 committed by GitHub
parent fdfb3896e9
commit 09fff08611
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 82 additions and 3 deletions

View File

@ -68,7 +68,19 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
} else if high_type.has_option_or_result() {
c.error('the `high` value in a `for x in low..high {` loop, cannot be Result or Option',
node.high.pos())
} else if node.cond is ast.Ident && node.val_var == node.cond.name {
if node.is_range {
c.error('in a `for x in <range>` loop, the key or value iteration variable `${node.val_var}` can not be the same as the low variable',
node.cond.pos())
} else {
c.error('in a `for x in array` loop, the key or value iteration variable `${node.val_var}` can not be the same as the low variable',
node.cond.pos())
}
} else if node.high is ast.Ident && node.val_var == node.high.name {
c.error('in a `for x in <range>` loop, the key or value iteration variable `${node.val_var}` can not be the same as the high variable',
node.high.pos())
}
if high_type in [ast.int_type, ast.int_literal_type] {
node.val_type = typ
} else {
@ -77,6 +89,10 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
node.high_type = high_type
node.scope.update_var_type(node.val_var, node.val_type)
} else {
if node.cond is ast.Ident && node.cond.name in [node.key_var, node.val_var] {
c.error('in a `for x in array` loop, the key or value iteration variable `${node.val_var}` can not be the same as the low variable',
node.cond.pos())
}
mut is_comptime := false
if (node.cond is ast.Ident && c.comptime.is_comptime_var(node.cond))
|| node.cond is ast.ComptimeSelector {

View File

@ -0,0 +1,47 @@
vlib/v/checker/for_in_same_var_err.vv:1:10: error: in a `for x in <range>` loop, the key or value iteration variable `x` can not be the same as the low variable
1 | for x in x .. 10 {
| ^
2 | dump(x)
3 | }
vlib/v/checker/for_in_same_var_err.vv:5:15: error: in a `for x in <range>` loop, the key or value iteration variable `y` can not be the same as the high variable
3 | }
4 |
5 | for y in 0 .. y {
| ^
6 | dump(y)
7 | }
vlib/v/checker/for_in_same_var_err.vv:9:10: error: in a `for x in <range>` loop, the key or value iteration variable `z` can not be the same as the low variable
7 | }
8 |
9 | for z in z .. z {
| ^
10 | dump(z)
11 | }
vlib/v/checker/for_in_same_var_err.vv:13:10: error: in a `for x in array` loop, the key or value iteration variable `w` can not be the same as the low variable
11 | }
12 |
13 | for w in w {
| ^
14 | dump(w)
15 | }
vlib/v/checker/for_in_same_var_err.vv:14:7: error: dump expression can not be void
12 |
13 | for w in w {
14 | dump(w)
| ^
15 | }
16 |
vlib/v/checker/for_in_same_var_err.vv:17:13: error: in a `for x in array` loop, the key or value iteration variable `_` can not be the same as the low variable
15 | }
16 |
17 | for k, _ in k {
| ^
18 | dump(k)
19 | }
vlib/v/checker/for_in_same_var_err.vv:17:13: error: for in: cannot index `int`
15 | }
16 |
17 | for k, _ in k {
| ^
18 | dump(k)
19 | }

View File

@ -0,0 +1,19 @@
for x in x .. 10 {
dump(x)
}
for y in 0 .. y {
dump(y)
}
for z in z .. z {
dump(z)
}
for w in w {
dump(w)
}
for k, _ in k {
dump(k)
}

View File

@ -146,9 +146,6 @@ fn (mut p Parser) for_stmt() ast.Stmt {
}
comments << p.eat_comments()
p.check(.key_in)
if p.tok.kind == .name && p.tok.lit in [key_var_name, val_var_name] {
return p.error('in a `for x in array` loop, the key or value iteration variable `${p.tok.lit}` can not be the same as the array variable')
}
comments << p.eat_comments()
// arr_expr
p.inside_for_expr = true