From 09fff08611f78994340a2f28a73a79b15ef68fc2 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 11 Dec 2024 09:31:31 -0300 Subject: [PATCH] checker: fix missing check on range expr when high var is same iteration value var (#23130) --- vlib/v/checker/for.v | 16 +++++++++ vlib/v/checker/for_in_same_var_err.out | 47 ++++++++++++++++++++++++++ vlib/v/checker/for_in_same_var_err.vv | 19 +++++++++++ vlib/v/parser/for.v | 3 -- 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 vlib/v/checker/for_in_same_var_err.out create mode 100644 vlib/v/checker/for_in_same_var_err.vv diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index f525b75ca4..2c96c41c0c 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -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 ` 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 ` 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 { diff --git a/vlib/v/checker/for_in_same_var_err.out b/vlib/v/checker/for_in_same_var_err.out new file mode 100644 index 0000000000..bc070af520 --- /dev/null +++ b/vlib/v/checker/for_in_same_var_err.out @@ -0,0 +1,47 @@ +vlib/v/checker/for_in_same_var_err.vv:1:10: error: in a `for x in ` 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 ` 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 ` 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 | } diff --git a/vlib/v/checker/for_in_same_var_err.vv b/vlib/v/checker/for_in_same_var_err.vv new file mode 100644 index 0000000000..314179117e --- /dev/null +++ b/vlib/v/checker/for_in_same_var_err.vv @@ -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) +} diff --git a/vlib/v/parser/for.v b/vlib/v/parser/for.v index 264345567a..9970721be1 100644 --- a/vlib/v/parser/for.v +++ b/vlib/v/parser/for.v @@ -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