diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7ab6945427..78576d9dd3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -31,7 +31,6 @@ pub mut: pref &pref.Preferences // Preferences shared from V struct in_for_count int // if checker is currently in an for loop // checked_ident string // to avoid infinit checker loops - var_decl_name string returns bool scope_returns bool mod string // current module name @@ -1258,9 +1257,6 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { if is_decl && ident.name != '_' { c.check_valid_snake_case(ident.name, 'variable name', ident.pos) } - if assign_stmt.op == .decl_assign { - c.var_decl_name = ident.name - } mut ident_var_info := ident.var_info() // c.assigned_var_name = ident.name if assign_stmt.op == .assign { @@ -1282,7 +1278,6 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { c.check_expr_opt_call(assign_stmt.right[i], assign_stmt.right_types[i], true) } } - c.var_decl_name = '' c.expected_type = table.void_type // c.assigned_var_name = '' } @@ -1823,11 +1818,6 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { } pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { - if ident.name == c.var_decl_name { // c.checked_ident { - // Do not allow `x := x` - c.error('unresolved: `$ident.name`', ident.pos) - return table.void_type - } // TODO: move this if c.const_deps.len > 0 { mut name := ident.name diff --git a/vlib/v/checker/tests/assign_expr_unresolved_variables_err_a.out b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_a.out new file mode 100644 index 0000000000..7daf00ca9c --- /dev/null +++ b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_a.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/assign_expr_unresolved_variables_err_a.v:2:7: error: unresolved variables `a` + 1 | fn main() { + 2 | a := a + | ^ + 3 | println(a) + 4 | } diff --git a/vlib/v/checker/tests/assign_expr_unresolved_variables_err_a.vv b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_a.vv new file mode 100644 index 0000000000..26ff9bb04a --- /dev/null +++ b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_a.vv @@ -0,0 +1,4 @@ +fn main() { + a := a + println(a) +} \ No newline at end of file diff --git a/vlib/v/checker/tests/assign_expr_unresolved_variables_err_b.out b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_b.out new file mode 100644 index 0000000000..35c836f7db --- /dev/null +++ b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_b.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/assign_expr_unresolved_variables_err_b.v:2:10: error: unresolved variables `a` + 1 | fn main() { + 2 | a, b := a, b + | ^ + 3 | println('$a, $b') + 4 | } diff --git a/vlib/v/checker/tests/assign_expr_unresolved_variables_err_b.vv b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_b.vv new file mode 100644 index 0000000000..8e9d236549 --- /dev/null +++ b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_b.vv @@ -0,0 +1,4 @@ +fn main() { + a, b := a, b + println('$a, $b') +} \ No newline at end of file diff --git a/vlib/v/checker/tests/assign_expr_unresolved_variables_err_c.out b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_c.out new file mode 100644 index 0000000000..3126e45e1a --- /dev/null +++ b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_c.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/assign_expr_unresolved_variables_err_c.v:2:10: error: unresolved variables `a` + 1 | fn main() { + 2 | a, b := a + 1, b * 3 + | ^ + 3 | println('$a, $b') + 4 | } diff --git a/vlib/v/checker/tests/assign_expr_unresolved_variables_err_c.vv b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_c.vv new file mode 100644 index 0000000000..de3950acb7 --- /dev/null +++ b/vlib/v/checker/tests/assign_expr_unresolved_variables_err_c.vv @@ -0,0 +1,4 @@ +fn main() { + a, b := a + 1, b * 3 + println('$a, $b') +} \ No newline at end of file diff --git a/vlib/v/parser/assign.v b/vlib/v/parser/assign.v index 43eba9d6bd..afc81badf0 100644 --- a/vlib/v/parser/assign.v +++ b/vlib/v/parser/assign.v @@ -9,6 +9,23 @@ fn (mut p Parser) assign_stmt() ast.Stmt { return p.partial_assign_stmt([]) } +fn (mut p Parser) check_unresolved_variables(idents []ast.Ident, expr ast.Expr) { + match expr { + ast.Ident { + for ident in idents { + if ident.name == it.name { + p.error_with_pos('unresolved variables `$it.name`', it.pos) + } + } + } + ast.InfixExpr { + p.check_unresolved_variables(idents, it.left) + p.check_unresolved_variables(idents, it.right) + } + else {} + } +} + fn (mut p Parser) partial_assign_stmt(known_lhs []ast.Ident) ast.Stmt { mut idents := known_lhs mut op := p.tok.kind @@ -24,6 +41,12 @@ fn (mut p Parser) partial_assign_stmt(known_lhs []ast.Ident) ast.Stmt { pos := p.tok.position() exprs := p.parse_assign_rhs() is_decl := op == .decl_assign + if is_decl { + // a, b := a + 1, b + for expr in exprs { + p.check_unresolved_variables(idents, expr) + } + } for i, ident in idents { known_var := p.scope.known_var(ident.name) if !is_decl && !known_var {