summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-10-07 19:08:04 +0200
committerBram Moolenaar <Bram@vim.org>2020-10-07 19:08:04 +0200
commit0876c78527469ddf50c23244566dd5bc35004307 (patch)
treeeaf6d8d402369fd5326ffe6f36b249c3e18c8f4e /src
parent9a033d7b18651acbb7eda4b7f39a27c01748fb70 (diff)
patch 8.2.1812: Vim9: nested closure throws an internal errorv8.2.1812
Problem: Vim9: nested closure throws an internal error. Solution: Do not skip a local variable with a partial. (closes #7065)
Diffstat (limited to 'src')
-rw-r--r--src/testdir/test_vim9_func.vim14
-rw-r--r--src/version.c2
-rw-r--r--src/vim9execute.c6
3 files changed, 20 insertions, 2 deletions
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index f3352453fe..c3687cf20a 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -1388,6 +1388,20 @@ def Test_double_closure_fails()
CheckScriptSuccess(lines)
enddef
+def Test_nested_closure_used()
+ var lines =<< trim END
+ vim9script
+ def Func()
+ var x = 'hello'
+ var Closure = {-> x}
+ g:Myclosure = {-> Closure()}
+ enddef
+ Func()
+ assert_equal('hello', g:Myclosure())
+ END
+ CheckScriptSuccess(lines)
+enddef
+
def Test_nested_closure_fails()
var lines =<< trim END
vim9script
diff --git a/src/version.c b/src/version.c
index a2929bc3f7..1c8629dd80 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1812,
+/**/
1811,
/**/
1810,
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 7afc5c27cd..2387ac9061 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -377,10 +377,11 @@ handle_closure_in_use(ectx_T *ectx, int free_arguments)
tv = STACK_TV(ectx->ec_frame_idx + STACK_FRAME_SIZE + idx);
// Do not copy a partial created for a local function.
- // TODO: this won't work if the closure actually uses it. But when
+ // TODO: This won't work if the closure actually uses it. But when
// keeping it it gets complicated: it will create a reference cycle
// inside the partial, thus needs special handling for garbage
// collection.
+ // For now, decide on the reference count.
if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL)
{
int i;
@@ -389,7 +390,8 @@ handle_closure_in_use(ectx_T *ectx, int free_arguments)
{
partial_T *pt = ((partial_T **)gap->ga_data)[gap->ga_len
- closure_count + i];
- if (tv->vval.v_partial == pt)
+
+ if (tv->vval.v_partial == pt && pt->pt_refcount < 2)
break;
}
if (i < closure_count)