]> granicus.if.org Git - vim/commitdiff
patch 8.2.3720: Vim9: Internal error when invoking closure in legacy context v8.2.3720
authorBram Moolenaar <Bram@vim.org>
Thu, 2 Dec 2021 16:38:52 +0000 (16:38 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 2 Dec 2021 16:38:52 +0000 (16:38 +0000)
Problem:    Vim9: Internal error when invoking closure in legacy context.
Solution:   Give a more appropriate error message. (closes #9251)

src/errors.h
src/testdir/test_vim9_func.vim
src/version.c
src/vim9execute.c

index e09ef53dced5e09fdc74c2d5569c7c06ce261ca3..1d6a3a3c661819622bd145cb8212368b55513142 100644 (file)
@@ -689,3 +689,5 @@ EXTERN char e_cannot_find_variable_to_unlock_str[]
        INIT(= N_("E1246: Cannot find variable to (un)lock: %s"));
 EXTERN char e_line_number_out_of_range[]
        INIT(= N_("E1247: Line number out of range"));
+EXTERN char e_closure_called_from_invalid_context[]
+       INIT(= N_("E1248: Closure called from invalid context"));
index 51b95ab6cf769c63a7462b7824e4fef4f8781bf5..651da050994fdb53405d70f8348228e0aea583d4 100644 (file)
@@ -2384,6 +2384,21 @@ def Test_global_closure_called_directly()
   delfunc g:Inner
 enddef
 
+def Test_closure_called_from_legacy()
+  var lines =<< trim END
+      vim9script
+      def Func()
+        var outer = 'foo'
+        var F = () => {
+              outer = 'bar'
+            }
+        execute printf('call %s()', string(F))
+      enddef
+      Func()
+  END
+  CheckScriptFailure(lines, 'E1248')
+enddef
+
 def Test_failure_in_called_function()
   # this was using the frame index as the return value
   var lines =<< trim END
index d977c653ad5c2352828b9570bdbe68613e3ee862..810567f40ea638d617dc8a644a72ca1bd0e3e300 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3720,
 /**/
     3719,
 /**/
index 4b2763b1f9106ef162858b2eb69d12659671437f..bd7f71e686880d4a0752bb750aea790143cf2cf8 100644 (file)
@@ -2733,7 +2733,13 @@ exec_instructions(ectx_T *ectx)
                    if (outer == NULL)
                    {
                        SOURCING_LNUM = iptr->isn_lnum;
-                       iemsg("LOADOUTER depth more than scope levels");
+                       if (ectx->ec_frame_idx == ectx->ec_initial_frame_idx
+                                                || ectx->ec_outer_ref == NULL)
+                           // Possibly :def function called from legacy
+                           // context.
+                           emsg(_(e_closure_called_from_invalid_context));
+                       else
+                           iemsg("LOADOUTER depth more than scope levels");
                        goto theend;
                    }
                    tv = ((typval_T *)outer->out_stack->ga_data)