summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-07-25 18:07:00 +0200
committerBram Moolenaar <Bram@vim.org>2021-07-25 18:07:00 +0200
commit3c77b6a1ce1d4a06c60bb9fae7eec2775f547d55 (patch)
tree271c375dca6f3163b0e829ccb59f176e33a96ba5
parenta764e73d4ffc5d046807c757eaacb9b0a5408152 (diff)
patch 8.2.3222: Vim9: cannot used loop variable later as lambda argumentv8.2.3222
Problem: Vim9: cannot used loop variable later as lambda argument. Solution: When not in function context check the current block ID. (closes #8637)
-rw-r--r--src/testdir/test_vim9_func.vim11
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c17
3 files changed, 27 insertions, 3 deletions
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index e8df8a75d5..144797edbb 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -2352,7 +2352,7 @@ def Test_list_lambda()
assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
enddef
-def Test_lamba_block_variable()
+def Test_lambda_block_variable()
var lines =<< trim END
vim9script
var flist: list<func>
@@ -2386,6 +2386,15 @@ def Test_lamba_block_variable()
endfor
END
CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
+
+ lines =<< trim END
+ vim9script
+ for i in range(10)
+ var Ref = () => 0
+ endfor
+ assert_equal(0, ((i) => 0)(0))
+ END
+ CheckScriptSuccess(lines)
enddef
def Test_legacy_lambda()
diff --git a/src/version.c b/src/version.c
index 7d66d8b5b6..f8a3ee4786 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3222,
+/**/
3221,
/**/
3220,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 2df5ff4f41..62d73733be 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -355,10 +355,23 @@ find_script_var(char_u *name, size_t len, cctx_T *cctx)
return NULL;
sav = HI2SAV(hi);
- if (sav->sav_block_id == 0 || cctx == NULL)
- // variable defined in the script scope or not in a function.
+ if (sav->sav_block_id == 0)
+ // variable defined in the top script scope is always visible
return sav;
+ if (cctx == NULL)
+ {
+ // Not in a function scope, find variable with block id equal to or
+ // smaller than the current block id.
+ while (sav != NULL)
+ {
+ if (sav->sav_block_id <= si->sn_current_block_id)
+ break;
+ sav = sav->sav_next;
+ }
+ return sav;
+ }
+
// Go over the variables with this name and find one that was visible
// from the function.
ufunc = cctx->ctx_ufunc;