forked from aniani/vim
patch 8.2.2191: Vim9: using wrong name with lambda in nested function
Problem: Vim9: using wrong name with lambda in nested function. Solution: Copy the lambda name earlier. (closes #7525)
This commit is contained in:
@@ -301,6 +301,19 @@ def Test_nested_global_function()
|
|||||||
CheckScriptFailure(lines, "E122:")
|
CheckScriptFailure(lines, "E122:")
|
||||||
delfunc g:Inner
|
delfunc g:Inner
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Outer()
|
||||||
|
def g:Inner()
|
||||||
|
echo map([1, 2, 3], {_, v -> v + 1})
|
||||||
|
enddef
|
||||||
|
g:Inner()
|
||||||
|
enddef
|
||||||
|
Outer()
|
||||||
|
END
|
||||||
|
CheckScriptSuccess(lines)
|
||||||
|
delfunc g:Inner
|
||||||
|
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
def Func()
|
def Func()
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2191,
|
||||||
/**/
|
/**/
|
||||||
2190,
|
2190,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -1428,20 +1428,27 @@ generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate an ISN_NEWFUNC instruction.
|
* Generate an ISN_NEWFUNC instruction.
|
||||||
|
* "lambda_name" and "func_name" must be in allocated memory and will be
|
||||||
|
* consumed.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
|
generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
|
||||||
{
|
{
|
||||||
isn_T *isn;
|
isn_T *isn;
|
||||||
char_u *name;
|
|
||||||
|
|
||||||
RETURN_OK_IF_SKIP(cctx);
|
if (cctx->ctx_skip == SKIP_YES)
|
||||||
name = vim_strsave(lambda_name);
|
{
|
||||||
if (name == NULL)
|
vim_free(lambda_name);
|
||||||
return FAIL;
|
vim_free(func_name);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
|
if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
|
||||||
|
{
|
||||||
|
vim_free(lambda_name);
|
||||||
|
vim_free(func_name);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
isn->isn_arg.newfunc.nf_lambda = name;
|
}
|
||||||
|
isn->isn_arg.newfunc.nf_lambda = lambda_name;
|
||||||
isn->isn_arg.newfunc.nf_global = func_name;
|
isn->isn_arg.newfunc.nf_global = func_name;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -4840,7 +4847,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
char_u *name_end = to_name_end(eap->arg, TRUE);
|
char_u *name_end = to_name_end(eap->arg, TRUE);
|
||||||
char_u *lambda_name;
|
char_u *lambda_name;
|
||||||
ufunc_T *ufunc;
|
ufunc_T *ufunc;
|
||||||
int r;
|
int r = FAIL;
|
||||||
|
|
||||||
if (eap->forceit)
|
if (eap->forceit)
|
||||||
{
|
{
|
||||||
@@ -4883,16 +4890,21 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
eap->cookie = cctx;
|
eap->cookie = cctx;
|
||||||
eap->skip = cctx->ctx_skip == SKIP_YES;
|
eap->skip = cctx->ctx_skip == SKIP_YES;
|
||||||
eap->forceit = FALSE;
|
eap->forceit = FALSE;
|
||||||
lambda_name = get_lambda_name();
|
lambda_name = vim_strsave(get_lambda_name());
|
||||||
|
if (lambda_name == NULL)
|
||||||
|
return NULL;
|
||||||
ufunc = define_function(eap, lambda_name);
|
ufunc = define_function(eap, lambda_name);
|
||||||
|
|
||||||
if (ufunc == NULL)
|
if (ufunc == NULL)
|
||||||
return eap->skip ? (char_u *)"" : NULL;
|
{
|
||||||
|
r = eap->skip ? OK : FAIL;
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
if (ufunc->uf_def_status == UF_TO_BE_COMPILED
|
if (ufunc->uf_def_status == UF_TO_BE_COMPILED
|
||||||
&& compile_def_function(ufunc, TRUE, cctx) == FAIL)
|
&& compile_def_function(ufunc, TRUE, cctx) == FAIL)
|
||||||
{
|
{
|
||||||
func_ptr_unref(ufunc);
|
func_ptr_unref(ufunc);
|
||||||
return NULL;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_global)
|
if (is_global)
|
||||||
@@ -4903,7 +4915,10 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
if (func_name == NULL)
|
if (func_name == NULL)
|
||||||
r = FAIL;
|
r = FAIL;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
r = generate_NEWFUNC(cctx, lambda_name, func_name);
|
r = generate_NEWFUNC(cctx, lambda_name, func_name);
|
||||||
|
lambda_name = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -4913,9 +4928,9 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
int block_depth = cctx->ctx_ufunc->uf_block_depth;
|
int block_depth = cctx->ctx_ufunc->uf_block_depth;
|
||||||
|
|
||||||
if (lvar == NULL)
|
if (lvar == NULL)
|
||||||
return NULL;
|
goto theend;
|
||||||
if (generate_FUNCREF(cctx, ufunc) == FAIL)
|
if (generate_FUNCREF(cctx, ufunc) == FAIL)
|
||||||
return NULL;
|
goto theend;
|
||||||
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
||||||
|
|
||||||
// copy over the block scope IDs
|
// copy over the block scope IDs
|
||||||
@@ -4930,8 +4945,11 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: warning for trailing text?
|
// TODO: warning for trailing text?
|
||||||
|
r = OK;
|
||||||
|
|
||||||
|
theend:
|
||||||
|
vim_free(lambda_name);
|
||||||
return r == FAIL ? NULL : (char_u *)"";
|
return r == FAIL ? NULL : (char_u *)"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user