Skip to content

Commit 86d8725

Browse files
committed
patch 9.0.0390: cannot use a partial with :defer
Problem: Cannot use a partial with :defer. Solution: Add the partial arguments before the other arguments. Disallow using a dictionary.
1 parent ccfde4d commit 86d8725

4 files changed

Lines changed: 57 additions & 5 deletions

File tree

src/errors.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3326,3 +3326,7 @@ EXTERN char e_non_null_list_required_for_argument_nr[]
33263326
#endif
33273327
EXTERN char e_window_unexpectedly_close_while_searching_for_tags[]
33283328
INIT(= N_("E1299: Window unexpectedly closed while searching for tags"));
3329+
#ifdef FEAT_EVAL
3330+
EXTERN char e_cannot_use_partial_with_dictionary_for_defer[]
3331+
INIT(= N_("E1300: Cannot use a partial with dictionary for :defer"));
3332+
#endif

src/testdir/test_user_func.vim

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,11 @@ func Test_funcdef_alloc_failure()
529529
bw!
530530
endfunc
531531

532-
func AddDefer(arg)
533-
call extend(g:deferred, [a:arg])
532+
func AddDefer(arg1, ...)
533+
call extend(g:deferred, [a:arg1])
534+
if a:0 == 1
535+
call extend(g:deferred, [a:1])
536+
endif
534537
endfunc
535538

536539
func WithDeferTwo()
@@ -550,6 +553,13 @@ func WithDeferOne()
550553
call extend(g:deferred, ['end One'])
551554
endfunc
552555

556+
func WithPartialDefer()
557+
call extend(g:deferred, ['in Partial'])
558+
let Part = funcref('AddDefer', ['arg1'])
559+
defer Part("arg2")
560+
call extend(g:deferred, ['end Partial'])
561+
endfunc
562+
553563
func Test_defer()
554564
let g:deferred = []
555565
call WithDeferOne()
@@ -558,6 +568,17 @@ func Test_defer()
558568
unlet g:deferred
559569

560570
call assert_equal('', glob('Xfuncdefer'))
571+
572+
call assert_fails('defer delete("Xfuncdefer")->Another()', 'E488:')
573+
call assert_fails('defer delete("Xfuncdefer").member', 'E488:')
574+
575+
let g:deferred = []
576+
call WithPartialDefer()
577+
call assert_equal(['in Partial', 'end Partial', 'arg1', 'arg2'], g:deferred)
578+
unlet g:deferred
579+
580+
let Part = funcref('AddDefer', ['arg1'], {})
581+
call assert_fails('defer Part("arg2")', 'E1300:')
561582
endfunc
562583

563584

src/userfunc.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5567,17 +5567,42 @@ ex_call_inner(
55675567
* Returns FAIL or OK.
55685568
*/
55695569
static int
5570-
ex_defer_inner(char_u *name, char_u **arg, evalarg_T *evalarg)
5570+
ex_defer_inner(
5571+
char_u *name,
5572+
char_u **arg,
5573+
partial_T *partial,
5574+
evalarg_T *evalarg)
55715575
{
55725576
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
5577+
int partial_argc = 0; // number of partial arguments
55735578
int argcount = 0; // number of arguments found
5579+
int r;
55745580

55755581
if (current_funccal == NULL)
55765582
{
55775583
semsg(_(e_str_not_inside_function), "defer");
55785584
return FAIL;
55795585
}
5580-
if (get_func_arguments(arg, evalarg, FALSE, argvars, &argcount) == FAIL)
5586+
if (partial != NULL)
5587+
{
5588+
if (partial->pt_dict != NULL)
5589+
{
5590+
emsg(_(e_cannot_use_partial_with_dictionary_for_defer));
5591+
return FAIL;
5592+
}
5593+
if (partial->pt_argc > 0)
5594+
{
5595+
int i;
5596+
5597+
partial_argc = partial->pt_argc;
5598+
for (i = 0; i < partial_argc; ++i)
5599+
copy_tv(&partial->pt_argv[i], &argvars[i]);
5600+
}
5601+
}
5602+
r = get_func_arguments(arg, evalarg, FALSE,
5603+
argvars + partial_argc, &argcount);
5604+
argcount += partial_argc;
5605+
if (r == FAIL)
55815606
{
55825607
while (--argcount >= 0)
55835608
clear_tv(&argvars[argcount]);
@@ -5738,7 +5763,7 @@ ex_call(exarg_T *eap)
57385763
if (eap->cmdidx == CMD_defer)
57395764
{
57405765
arg = startarg;
5741-
failed = ex_defer_inner(name, &arg, &evalarg) == FAIL;
5766+
failed = ex_defer_inner(name, &arg, partial, &evalarg) == FAIL;
57425767
}
57435768
else
57445769
{

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,8 @@ static char *(features[]) =
703703

704704
static int included_patches[] =
705705
{ /* Add new patch number below this line */
706+
/**/
707+
390,
706708
/**/
707709
389,
708710
/**/

0 commit comments

Comments
 (0)