]> granicus.if.org Git - vim/commitdiff
patch 8.2.3222: Vim9: cannot used loop variable later as lambda argument v8.2.3222
authorBram Moolenaar <Bram@vim.org>
Sun, 25 Jul 2021 16:07:00 +0000 (18:07 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 25 Jul 2021 16:07:00 +0000 (18:07 +0200)
Problem:    Vim9: cannot used loop variable later as lambda argument.
Solution:   When not in function context check the current block ID.
            (closes #8637)

src/testdir/test_vim9_func.vim
src/version.c
src/vim9compile.c

index e8df8a75d5d25759d8b3e6444bcb3d976f5430e1..144797edbb0860a9434c01551843eca522907113 100644 (file)
@@ -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()
index 7d66d8b5b6d4cd897a231ce140b27b355697c0e6..f8a3ee47862f8a289d2be6f3928d1cde85535419 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3222,
 /**/
     3221,
 /**/
index 2df5ff4f413d709a4970f5a0651027969dd2d6d9..62d73733be49727cf0d796a0060eeda90402991e 100644 (file)
@@ -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;