diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 99b2a113acbe858e39d142606dc072379637ab75..82146756f019b776c3f398fdbe5796b25e6eed91 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -1019,5 +1019,24 @@ def Test_recursive_call()
   assert_equal(6765, Fibonacci(20))
 enddef
 
+def TreeWalk(dir: string): list<any>
+  return readdir(dir)->map({_, val ->
+            fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
+               ? {val : TreeWalk(dir .. '/' .. val)}
+               : val
+             })
+enddef
+
+def Test_closure_in_map()
+  mkdir('XclosureDir/tdir', 'p')
+  writefile(['111'], 'XclosureDir/file1')
+  writefile(['222'], 'XclosureDir/file2')
+  writefile(['333'], 'XclosureDir/tdir/file3')
+
+  assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir'))
+
+  delete('XclosureDir', 'rf')
+enddef
+
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/version.c b/src/version.c
index 2c9c4f07a5a1c1899e2b860249cefec1c9f4222b..ddc6f2e066e7e9352b0a456fac811097c6abcc05 100644
--- 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 */
+/**/
+    1202,
 /**/
     1201,
 /**/
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 5fdbfbf5185fa0bea0ecc23f67ebfa36bd4ac4f4..eb900c876ff6c054f616f9aa23ba205f18179b1c 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -461,6 +461,10 @@ call_prepare(int argcount, typval_T *argvars, ectx_T *ectx)
     return OK;
 }
 
+// Ugly global to avoid passing the execution context around through many
+// layers.
+static ectx_T *current_ectx = NULL;
+
 /*
  * Call a builtin function by index.
  */
@@ -470,12 +474,16 @@ call_bfunc(int func_idx, int argcount, ectx_T *ectx)
     typval_T	argvars[MAX_FUNC_ARGS];
     int		idx;
     int		did_emsg_before = did_emsg;
+    ectx_T	*prev_ectx = current_ectx;
 
     if (call_prepare(argcount, argvars, ectx) == FAIL)
 	return FAIL;
 
-    // Call the builtin function.
+    // Call the builtin function.  Set "current_ectx" so that when it
+    // recursively invokes call_def_function() a closure context can be set.
+    current_ectx = ectx;
     call_internal_func_by_idx(func_idx, argvars, STACK_TV_BOT(-1));
+    current_ectx = prev_ectx;
 
     // Clear the arguments.
     for (idx = 0; idx < argcount; ++idx)
@@ -749,8 +757,17 @@ call_def_function(
 
     if (partial != NULL)
     {
-	ectx.ec_outer_stack = partial->pt_ectx_stack;
-	ectx.ec_outer_frame = partial->pt_ectx_frame;
+	if (partial->pt_ectx_stack == NULL && current_ectx != NULL)
+	{
+	    // TODO: is this always the right way?
+	    ectx.ec_outer_stack = &current_ectx->ec_stack;
+	    ectx.ec_outer_frame = current_ectx->ec_frame_idx;
+	}
+	else
+	{
+	    ectx.ec_outer_stack = partial->pt_ectx_stack;
+	    ectx.ec_outer_frame = partial->pt_ectx_frame;
+	}
     }
 
     // dummy frame entries