From 69c76171f1a78b829196f72d7010fbe1d9ad2944 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 2 Dec 2021 16:38:52 +0000 Subject: [PATCH] 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 #9251) --- src/errors.h | 2 ++ src/testdir/test_vim9_func.vim | 15 +++++++++++++++ src/version.c | 2 ++ src/vim9execute.c | 8 +++++++- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/errors.h b/src/errors.h index e09ef53dc..1d6a3a3c6 100644 --- a/src/errors.h +++ b/src/errors.h @@ -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")); diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 51b95ab6c..651da0509 100644 --- 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 diff --git a/src/version.c b/src/version.c index d977c653a..810567f40 100644 --- a/src/version.c +++ b/src/version.c @@ -753,6 +753,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 3720, /**/ 3719, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index 4b2763b1f..bd7f71e68 100644 --- 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) -- 2.40.0