Skip to content

Commit

Permalink
patch 8.2.2739: Vim9: a lambda accepts too many arguments at the scri…
Browse files Browse the repository at this point in the history
…pt level

Problem:    Vim9: a lambda accepts too many arguments at the script level.
Solution:   Do not set uf_varargs in Vim9 script.
  • Loading branch information
brammool committed Apr 9, 2021
1 parent dcae51f commit 767034c
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 5 deletions.
9 changes: 7 additions & 2 deletions src/testdir/test_vim9_func.vim
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,11 @@ def Test_call_lambda_args()
enddef
END
CheckDefFailure(lines, 'E1167:')

lines =<< trim END
echo ((a) => a)('aa', 'bb')
END
CheckDefAndScriptFailure(lines, 'E118:', 1)
enddef

def FilterWithCond(x: string, Cond: func(string): bool): bool
Expand Down Expand Up @@ -2114,7 +2119,7 @@ def Test_list_lambda()
->substitute("('", ' ', '')
->substitute("')", '', '')
->substitute('function\zs', ' ', ''))
assert_match('def <lambda>\d\+(_: any, ...): number\n1 return 0\n enddef', body)
assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
enddef

def DoFilterThis(a: string): list<string>
Expand Down Expand Up @@ -2363,7 +2368,7 @@ def Test_did_emsg_reset()
vim9script
au BufWinLeave * #
def Func()
popup_menu('', {callback: () => popup_create('', {})->popup_close()})
popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
eval [][0]
enddef
nno <F3> <cmd>call <sid>Func()<cr>
Expand Down
2 changes: 1 addition & 1 deletion src/testdir/test_vim9_script.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3518,7 +3518,7 @@ func Test_no_redraw_when_restoring_cpo()
vim9script
set cpo+=M
exe 'set rtp^=' .. getcwd() .. '/Xdir'
au CmdlineEnter : ++once timer_start(0, () => script#func())
au CmdlineEnter : ++once timer_start(0, (_) => script#func())
setline(1, 'some text')
END
call writefile(lines, 'XTest_redraw_cpo')
Expand Down
5 changes: 3 additions & 2 deletions src/userfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1263,8 +1263,9 @@ get_lambda_tv(
#endif
if (sandbox)
flags |= FC_SANDBOX;
// can be called with more args than uf_args.ga_len
fp->uf_varargs = TRUE;
// In legacy script a lambda can be called with more args than
// uf_args.ga_len.
fp->uf_varargs = !in_vim9script();
fp->uf_flags = flags;
fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx;
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2739,
/**/
2738,
/**/
Expand Down

3 comments on commit 767034c

@lacygoill
Copy link

@lacygoill lacygoill commented on 767034c Apr 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether the error message should be improved when passing too many arguments in a :def function.

At the script level:

vim9script
var s = 'asdf'->((a) => a)('x')
E118: Too many arguments for function: <lambda>1

In a :def function:

vim9script
def Func()
    var s = 'asdf'->((a) => a)('x')
enddef
defcompile
E118: Too many arguments for function: [expression]

[expression] looks a bit weird. Maybe <lambda>1 would be better and more consistent. Although, it might not be very useful, because – even at the script level – we can't use the name to get the definition:

:def <lambda>1
E123: Undefined function: <lambda>1

I guess that's because the lambda only exists while evaluating the expression, and is automatically removed afterward.

@lacygoill
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe giving the body of the lambda would be more helpful:

E118: Too many arguments for function: (a) => a

@brammool
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the lambda doesn't really have a name, thus it really is an expression. It's hard to do anything else than to mention the line number.

Please sign in to comment.