changeset 25370:d52504ef26ed v8.2.3222

patch 8.2.3222: Vim9: cannot used loop variable later as lambda argument Commit: https://github.com/vim/vim/commit/3c77b6a1ce1d4a06c60bb9fae7eec2775f547d55 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 25 18:07:00 2021 +0200 patch 8.2.3222: Vim9: cannot used loop variable later as lambda argument Problem: Vim9: cannot used loop variable later as lambda argument. Solution: When not in function context check the current block ID. (closes #8637)
author Bram Moolenaar <Bram@vim.org>
date Sun, 25 Jul 2021 18:15:02 +0200
parents 1624e9d9a4d9
children e14bafcbce5c
files src/testdir/test_vim9_func.vim src/version.c src/vim9compile.c
diffstat 3 files changed, 27 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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()
--- 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,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -355,10 +355,23 @@ find_script_var(char_u *name, size_t len
 	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;