]> granicus.if.org Git - vim/commitdiff
patch 8.2.2191: Vim9: using wrong name with lambda in nested function v8.2.2191
authorBram Moolenaar <Bram@vim.org>
Tue, 22 Dec 2020 17:56:55 +0000 (18:56 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 22 Dec 2020 17:56:55 +0000 (18:56 +0100)
Problem:    Vim9: using wrong name with lambda in nested function.
Solution:   Copy the lambda name earlier. (closes #7525)

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

index 3b57e312b8cac7f390c3933c12a5b4eddf11030b..eadd1d1c3f91389dd59db82759bdb5ef4d4f1696 100644 (file)
@@ -301,6 +301,19 @@ def Test_nested_global_function()
   CheckScriptFailure(lines, "E122:")
   delfunc g:Inner
 
+  lines =<< trim END
+      vim9script
+      def Outer()
+        def g:Inner()
+          echo map([1, 2, 3], {_, v -> v + 1})
+        enddef
+        g:Inner()
+      enddef
+      Outer()
+  END
+  CheckScriptSuccess(lines)
+  delfunc g:Inner
+
   lines =<< trim END
       vim9script
       def Func()
index 427c8f8a7f623f36746f71d8a4418d75b9fd8053..9a5a41402b3f0beede9de66060756f59b8443592 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2191,
 /**/
     2190,
 /**/
index 7ee15fe2759774036db58d0221533d359ffda1e8..b3d591d2366e230228aca254c3d1f44c6aa0a69f 100644 (file)
@@ -1428,20 +1428,27 @@ generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
 
 /*
  * Generate an ISN_NEWFUNC instruction.
+ * "lambda_name" and "func_name" must be in allocated memory and will be
+ * consumed.
  */
     static int
 generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
 {
     isn_T      *isn;
-    char_u     *name;
 
-    RETURN_OK_IF_SKIP(cctx);
-    name = vim_strsave(lambda_name);
-    if (name == NULL)
-       return FAIL;
+    if (cctx->ctx_skip == SKIP_YES)
+    {
+       vim_free(lambda_name);
+       vim_free(func_name);
+       return OK;
+    }
     if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
+    {
+       vim_free(lambda_name);
+       vim_free(func_name);
        return FAIL;
-    isn->isn_arg.newfunc.nf_lambda = name;
+    }
+    isn->isn_arg.newfunc.nf_lambda = lambda_name;
     isn->isn_arg.newfunc.nf_global = func_name;
 
     return OK;
@@ -4840,7 +4847,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
     char_u     *name_end = to_name_end(eap->arg, TRUE);
     char_u     *lambda_name;
     ufunc_T    *ufunc;
-    int                r;
+    int                r = FAIL;
 
     if (eap->forceit)
     {
@@ -4883,16 +4890,21 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
     eap->cookie = cctx;
     eap->skip = cctx->ctx_skip == SKIP_YES;
     eap->forceit = FALSE;
-    lambda_name = get_lambda_name();
+    lambda_name = vim_strsave(get_lambda_name());
+    if (lambda_name == NULL)
+       return NULL;
     ufunc = define_function(eap, lambda_name);
 
     if (ufunc == NULL)
-       return eap->skip ? (char_u *)"" : NULL;
+    {
+       r = eap->skip ? OK : FAIL;
+       goto theend;
+    }
     if (ufunc->uf_def_status == UF_TO_BE_COMPILED
            && compile_def_function(ufunc, TRUE, cctx) == FAIL)
     {
        func_ptr_unref(ufunc);
-       return NULL;
+       goto theend;
     }
 
     if (is_global)
@@ -4903,7 +4915,10 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
        if (func_name == NULL)
            r = FAIL;
        else
+       {
            r = generate_NEWFUNC(cctx, lambda_name, func_name);
+           lambda_name = NULL;
+       }
     }
     else
     {
@@ -4913,9 +4928,9 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
        int block_depth = cctx->ctx_ufunc->uf_block_depth;
 
        if (lvar == NULL)
-           return NULL;
+           goto theend;
        if (generate_FUNCREF(cctx, ufunc) == FAIL)
-           return NULL;
+           goto theend;
        r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
 
        // copy over the block scope IDs
@@ -4930,8 +4945,11 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
            }
        }
     }
-
     // TODO: warning for trailing text?
+    r = OK;
+
+theend:
+    vim_free(lambda_name);
     return r == FAIL ? NULL : (char_u *)"";
 }