changeset 26378:a926ccd92ae1 v8.2.3720

patch 8.2.3720: Vim9: Internal error when invoking closure in legacy context Commit: https://github.com/vim/vim/commit/69c76171f1a78b829196f72d7010fbe1d9ad2944 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Dec 2 16:38:52 2021 +0000 patch 8.2.3720: Vim9: Internal error when invoking closure in legacy context Problem: Vim9: Internal error when invoking closure in legacy context. Solution: Give a more appropriate error message. (closes https://github.com/vim/vim/issues/9251)
author Bram Moolenaar <Bram@vim.org>
date Thu, 02 Dec 2021 17:45:03 +0100
parents 8c115ef03db5
children f6e050c67b71
files src/errors.h src/testdir/test_vim9_func.vim src/version.c src/vim9execute.c
diffstat 4 files changed, 26 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/errors.h
+++ b/src/errors.h
@@ -689,3 +689,5 @@ EXTERN char e_cannot_find_variable_to_un
 	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"));
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -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
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3720,
+/**/
     3719,
 /**/
     3718,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -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)