changeset 21757:6c03897bcd60 v8.2.1428

patch 8.2.1428: Vim9: :def function does not abort on nested function error Commit: https://github.com/vim/vim/commit/ed677f5587af366f185f8922b7dde4a98c884328 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Aug 12 16:38:10 2020 +0200 patch 8.2.1428: Vim9: :def function does not abort on nested function error Problem: Vim9: :def function does not abort on nested function error. Solution: Check whether an error message was given. (closes https://github.com/vim/vim/issues/6691)
author Bram Moolenaar <Bram@vim.org>
date Wed, 12 Aug 2020 16:45:04 +0200
parents 067db9f81e68
children 465936f1ec7a
files src/testdir/test_vim9_script.vim src/version.c src/vim9execute.c
diffstat 3 files changed, 30 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1054,6 +1054,24 @@ def Test_throw_vimscript()
   CheckScriptSuccess(lines)
 enddef
 
+def Test_error_in_nested_function()
+  # an error in a nested :function aborts executin in the calling :def function
+  let lines =<< trim END
+      vim9script
+      def Func()
+        Error()
+        g:test_var = 1
+      enddef
+      func Error() abort
+        eval [][0]
+      endfunc
+      Func()
+  END
+  g:test_var = 0
+  CheckScriptFailure(lines, 'E684:')
+  assert_equal(0, g:test_var)
+enddef
+
 def Test_cexpr_vimscript()
   # only checks line continuation
   set errorformat=File\ %f\ line\ %l
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1428,
+/**/
     1427,
 /**/
     1426,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -505,6 +505,7 @@ call_ufunc(ufunc_T *ufunc, int argcount,
     funcexe_T   funcexe;
     int		error;
     int		idx;
+    int		called_emsg_before = called_emsg;
 
     if (ufunc->uf_def_status == UF_TO_BE_COMPILED
 	    && compile_def_function(ufunc, FALSE, NULL) == FAIL)
@@ -542,6 +543,9 @@ call_ufunc(ufunc_T *ufunc, int argcount,
 	user_func_error(error, ufunc->uf_name);
 	return FAIL;
     }
+    if (called_emsg > called_emsg_before)
+	// Error other than from calling the function itself.
+	return FAIL;
     return OK;
 }
 
@@ -670,10 +674,11 @@ store_var(char_u *name, typval_T *tv)
     static int
 call_eval_func(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr)
 {
-    int		called_emsg_before = called_emsg;
-
-    if (call_by_name(name, argcount, ectx, iptr) == FAIL
-					  && called_emsg == called_emsg_before)
+    int	    called_emsg_before = called_emsg;
+    int	    res;
+
+    res = call_by_name(name, argcount, ectx, iptr);
+    if (res == FAIL && called_emsg == called_emsg_before)
     {
 	dictitem_T	*v;
 
@@ -690,7 +695,7 @@ call_eval_func(char_u *name, int argcoun
 	}
 	return call_partial(&v->di_tv, argcount, ectx);
     }
-    return OK;
+    return res;
 }
 
 /*