Skip to content

Commit f0e86a0

Browse files
committed
patch 7.4.1607
Problem: Comparing a function that exists on two dicts is not backwards compatible. (Thinca) Solution: Only compare the function, not what the partial adds.
1 parent 953cc7f commit f0e86a0

4 files changed

Lines changed: 44 additions & 31 deletions

File tree

src/eval.c

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,33 +4555,14 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
45554555
else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC
45564556
|| rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL)
45574557
{
4558-
if (rettv->v_type != var2.v_type
4559-
|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
4558+
if (type != TYPE_EQUAL && type != TYPE_NEQUAL)
45604559
{
4561-
if (rettv->v_type != var2.v_type)
4562-
EMSG(_("E693: Can only compare Funcref with Funcref"));
4563-
else
4564-
EMSG(_("E694: Invalid operation for Funcrefs"));
4560+
EMSG(_("E694: Invalid operation for Funcrefs"));
45654561
clear_tv(rettv);
45664562
clear_tv(&var2);
45674563
return FAIL;
45684564
}
4569-
else if (rettv->v_type == VAR_PARTIAL)
4570-
{
4571-
/* Partials are only equal when identical. */
4572-
n1 = rettv->vval.v_partial != NULL
4573-
&& rettv->vval.v_partial == var2.vval.v_partial;
4574-
}
4575-
else
4576-
{
4577-
/* Compare two Funcrefs for being equal or unequal. */
4578-
if (rettv->vval.v_string == NULL
4579-
|| var2.vval.v_string == NULL)
4580-
n1 = FALSE;
4581-
else
4582-
n1 = STRCMP(rettv->vval.v_string,
4583-
var2.vval.v_string) == 0;
4584-
}
4565+
n1 = tv_equal(rettv, &var2, FALSE, FALSE);
45854566
if (type == TYPE_NEQUAL)
45864567
n1 = !n1;
45874568
}
@@ -6203,6 +6184,19 @@ tv_equal(
62036184
static int recursive_cnt = 0; /* catch recursive loops */
62046185
int r;
62056186

6187+
/* For VAR_FUNC and VAR_PARTIAL only compare the function name. */
6188+
if ((tv1->v_type == VAR_FUNC
6189+
|| (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
6190+
&& (tv2->v_type == VAR_FUNC
6191+
|| (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
6192+
{
6193+
s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
6194+
: tv1->vval.v_partial->pt_name;
6195+
s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
6196+
: tv2->vval.v_partial->pt_name;
6197+
return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0);
6198+
}
6199+
62066200
if (tv1->v_type != tv2->v_type)
62076201
return FALSE;
62086202

@@ -6234,15 +6228,6 @@ tv_equal(
62346228
--recursive_cnt;
62356229
return r;
62366230

6237-
case VAR_FUNC:
6238-
return (tv1->vval.v_string != NULL
6239-
&& tv2->vval.v_string != NULL
6240-
&& STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0);
6241-
6242-
case VAR_PARTIAL:
6243-
return tv1->vval.v_partial != NULL
6244-
&& tv1->vval.v_partial == tv2->vval.v_partial;
6245-
62466231
case VAR_NUMBER:
62476232
return tv1->vval.v_number == tv2->vval.v_number;
62486233

@@ -6266,6 +6251,8 @@ tv_equal(
62666251
#ifdef FEAT_JOB_CHANNEL
62676252
return tv1->vval.v_channel == tv2->vval.v_channel;
62686253
#endif
6254+
case VAR_FUNC:
6255+
case VAR_PARTIAL:
62696256
case VAR_UNKNOWN:
62706257
break;
62716258
}

src/testdir/test_alot.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ source test_assign.vim
55
source test_cursor_func.vim
66
source test_delete.vim
77
source test_ex_undo.vim
8+
source test_expr.vim
89
source test_expand.vim
910
source test_feedkeys.vim
1011
source test_file_perm.vim

src/testdir/test_expr.vim

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
" Tests for expressions.
2+
3+
func Test_equal()
4+
let base = {}
5+
func base.method()
6+
return 1
7+
endfunc
8+
func base.other() dict
9+
return 1
10+
endfunc
11+
let instance = copy(base)
12+
call assert_true(base.method == instance.method)
13+
call assert_true([base.method] == [instance.method])
14+
call assert_true(base.other == instance.other)
15+
call assert_true([base.other] == [instance.other])
16+
17+
call assert_false(base.method == base.other)
18+
call assert_false([base.method] == [base.other])
19+
call assert_false(base.method == instance.other)
20+
call assert_false([base.method] == [instance.other])
21+
22+
call assert_fails('echo base.method > instance.method')
23+
endfunc

src/version.c

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

749749
static int included_patches[] =
750750
{ /* Add new patch number below this line */
751+
/**/
752+
1607,
751753
/**/
752754
1606,
753755
/**/

0 commit comments

Comments
 (0)