From 6db62e43d39a50180a1ca7927f95d00379124ad7 Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 26 May 2023 08:29:52 +0800 Subject: [PATCH] parser: fix array method using `it` in defer (fix #18246) (#18267) --- vlib/v/parser/expr.v | 7 +---- vlib/v/parser/parser.v | 30 ++++++++----------- .../array_method_using_it_in_defer_test.v | 9 ++++++ 3 files changed, 22 insertions(+), 24 deletions(-) create mode 100644 vlib/v/tests/array_method_using_it_in_defer_test.v diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index a860639954..51f906bc4d 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -37,12 +37,7 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { .key_mut, .key_shared, .key_atomic, .key_static, .key_volatile { ident := p.ident(ast.Language.v) node = ident - if p.inside_defer { - if !p.defer_vars.any(it.name == ident.name && it.mod == ident.mod) - && ident.name != 'err' { - p.defer_vars << ident - } - } + p.add_defer_var(ident) p.is_stmt_ident = is_stmt_ident } .name, .question { diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 72da5531b8..29b4d844ec 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2557,12 +2557,7 @@ fn (mut p Parser) name_expr() ast.Expr { // incomplete module selector must be handled by dot_expr instead ident := p.ident(language) node = ident - if p.inside_defer { - if !p.defer_vars.any(it.name == ident.name && it.mod == ident.mod) - && ident.name != 'err' { - p.defer_vars << ident - } - } + p.add_defer_var(ident) return node } } @@ -2588,12 +2583,7 @@ fn (mut p Parser) name_expr() ast.Expr { if !same_line && p.peek_tok.kind == .lpar { ident := p.ident(language) node = ident - if p.inside_defer { - if !p.defer_vars.any(it.name == ident.name && it.mod == ident.mod) - && ident.name != 'err' { - p.defer_vars << ident - } - } + p.add_defer_var(ident) } else if p.peek_tok.kind == .lpar || is_generic_call || is_generic_cast || (p.tok.kind == .lsbr && p.peek_tok.kind == .rsbr && (p.peek_token(3).kind == .lpar || p.peek_token(5).kind == .lpar)) || (p.tok.kind == .lsbr && p.peek_tok.kind == .number @@ -2794,12 +2784,7 @@ fn (mut p Parser) name_expr() ast.Expr { } ident := p.ident(language) node = ident - if p.inside_defer { - if !p.defer_vars.any(it.name == ident.name && it.mod == ident.mod) - && ident.name != 'err' { - p.defer_vars << ident - } - } + p.add_defer_var(ident) } p.expr_mod = '' return node @@ -4338,3 +4323,12 @@ fn (mut p Parser) show(params ParserShowParams) { location := '${p.file_display_path}:${p.tok.line_nr}:' println('>> ${location:-40s} ${params.msg} ${context.join(' ')}') } + +fn (mut p Parser) add_defer_var(ident ast.Ident) { + if p.inside_defer { + if !p.defer_vars.any(it.name == ident.name && it.mod == ident.mod) + && ident.name !in ['err', 'it'] { + p.defer_vars << ident + } + } +} diff --git a/vlib/v/tests/array_method_using_it_in_defer_test.v b/vlib/v/tests/array_method_using_it_in_defer_test.v new file mode 100644 index 0000000000..80067ef520 --- /dev/null +++ b/vlib/v/tests/array_method_using_it_in_defer_test.v @@ -0,0 +1,9 @@ +fn test_array_method_using_it_in_defer() { + arr := ['1', '1.1', '1.2', '2', '2.1', '2.2'] + + defer { + ret := arr.filter(it.contains('1')) + println(ret) + assert ret == ['1', '1.1', '1.2', '2.1'] + } +}