Commit: patch 9.2.0878: Vim9: cannot use a script variable of an enclosing block in a lambda
Christian Brabandt <[email protected]> Thu, 30 Jul 2026 21:00:06 +0200
| Newsgroups | gmane.editors.vim.devel |
|---|---|
| Message-ID | <[email protected]> |
patch 9.2.0878: Vim9: cannot use a script variable of an enclosing block in a lambda Commit: https://github.com/vim/vim/commit/ce55a4910dc7a1de95d828ddce916d2d2bd4d6d6 Author: Hirohito Higashi <[email protected]> Date: Thu Jul 30 18:49:22 2026 +0000 patch 9.2.0878: Vim9: cannot use a script variable of an enclosing block in a lambda Problem: Vim9: E1001 when a lambda inside a :def function uses a script variable that was declared in an enclosing block, while the :def function itself can use it (neoharju) Solution: Copy the block scope IDs to the lambda, like it is done for a nested function (Hirohito Higashi). fixes: #20876 closes: #PR Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Signed-off-by: Hirohito Higashi <[email protected]> Signed-off-by: Christian Brabandt <[email protected]> diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 91873845d..b86acd071 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -449,6 +449,24 @@ def Test_block_local_vars_with_func() assert_equal(['foo', 'bar'], Func()) END v9.CheckScriptSuccess(lines) + + # also when the variables are used in a lambda inside the function + lines =<< trim END + vim9script + if true + var foo = 'foo' + if true + var bar = 'bar' + def Func(): list<string> + var Lambda = () => [foo, bar] + return Lambda() + enddef + defcompile + endif + endif + assert_equal(['foo', 'bar'], Func()) + END + v9.CheckScriptSuccess(lines) enddef " legacy func for command that's defined later diff --git a/src/version.c b/src/version.c index 3fba5845f..0e5c697ec 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 878, /**/ 877, /**/ diff --git a/src/vim9expr.c b/src/vim9expr.c index f69488d5b..7f47d82fb 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -1795,10 +1795,27 @@ compile_lambda(char_u **arg, cctx_T *cctx) clear_tv(&rettv); if (cctx->ctx_ufunc != NULL) + { // This lambda might be defined in a class method. Inherit the class // from the current function. ufunc->uf_defclass = cctx->ctx_ufunc->uf_defclass; + // Copy over the block scope IDs, so that a script variable declared in + // an enclosing block can be found. + int block_depth = cctx->ctx_ufunc->uf_block_depth; + + if (block_depth > 0) + { + ufunc->uf_block_ids = ALLOC_MULT(int, block_depth); + if (ufunc->uf_block_ids != NULL) + { + mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids, + sizeof(int) * block_depth); + ufunc->uf_block_depth = block_depth; + } + } + } + // Compile it here to get the return type. The return type is optional, // when it's missing use t_unknown. This is recognized in // compile_return(). -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wpVzC-004Zfc-6i%40256bit.org.