# HG changeset patch # User Christian Brabandt # Date 1458413105 -3600 # Node ID 3a38d465f7319bb0a927c07f86642be9012f041f # Parent 416fa8415adacb16db283442a1aab67e6f11840d commit https://github.com/vim/vim/commit/f0e86a0dbddc18568910e9e4aaae0cd88ca8087a Author: Bram Moolenaar Date: Sat Mar 19 19:38:12 2016 +0100 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. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -4555,33 +4555,14 @@ eval4(char_u **arg, typval_T *rettv, int else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL) { - if (rettv->v_type != var2.v_type - || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) - { - if (rettv->v_type != var2.v_type) - EMSG(_("E693: Can only compare Funcref with Funcref")); - else - EMSG(_("E694: Invalid operation for Funcrefs")); + if (type != TYPE_EQUAL && type != TYPE_NEQUAL) + { + EMSG(_("E694: Invalid operation for Funcrefs")); clear_tv(rettv); clear_tv(&var2); return FAIL; } - else if (rettv->v_type == VAR_PARTIAL) - { - /* Partials are only equal when identical. */ - n1 = rettv->vval.v_partial != NULL - && rettv->vval.v_partial == var2.vval.v_partial; - } - else - { - /* Compare two Funcrefs for being equal or unequal. */ - if (rettv->vval.v_string == NULL - || var2.vval.v_string == NULL) - n1 = FALSE; - else - n1 = STRCMP(rettv->vval.v_string, - var2.vval.v_string) == 0; - } + n1 = tv_equal(rettv, &var2, FALSE, FALSE); if (type == TYPE_NEQUAL) n1 = !n1; } @@ -6203,6 +6184,19 @@ tv_equal( static int recursive_cnt = 0; /* catch recursive loops */ int r; + /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ + if ((tv1->v_type == VAR_FUNC + || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) + && (tv2->v_type == VAR_FUNC + || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) + { + s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string + : tv1->vval.v_partial->pt_name; + s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string + : tv2->vval.v_partial->pt_name; + return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0); + } + if (tv1->v_type != tv2->v_type) return FALSE; @@ -6234,15 +6228,6 @@ tv_equal( --recursive_cnt; return r; - case VAR_FUNC: - return (tv1->vval.v_string != NULL - && tv2->vval.v_string != NULL - && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); - - case VAR_PARTIAL: - return tv1->vval.v_partial != NULL - && tv1->vval.v_partial == tv2->vval.v_partial; - case VAR_NUMBER: return tv1->vval.v_number == tv2->vval.v_number; @@ -6266,6 +6251,8 @@ tv_equal( #ifdef FEAT_JOB_CHANNEL return tv1->vval.v_channel == tv2->vval.v_channel; #endif + case VAR_FUNC: + case VAR_PARTIAL: case VAR_UNKNOWN: break; } diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim --- a/src/testdir/test_alot.vim +++ b/src/testdir/test_alot.vim @@ -5,6 +5,7 @@ source test_assign.vim source test_cursor_func.vim source test_delete.vim source test_ex_undo.vim +source test_expr.vim source test_expand.vim source test_feedkeys.vim source test_file_perm.vim diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim new file mode 100644 --- /dev/null +++ b/src/testdir/test_expr.vim @@ -0,0 +1,23 @@ +" Tests for expressions. + +func Test_equal() + let base = {} + func base.method() + return 1 + endfunc + func base.other() dict + return 1 + endfunc + let instance = copy(base) + call assert_true(base.method == instance.method) + call assert_true([base.method] == [instance.method]) + call assert_true(base.other == instance.other) + call assert_true([base.other] == [instance.other]) + + call assert_false(base.method == base.other) + call assert_false([base.method] == [base.other]) + call assert_false(base.method == instance.other) + call assert_false([base.method] == [instance.other]) + + call assert_fails('echo base.method > instance.method') +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -749,6 +749,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1607, +/**/ 1606, /**/ 1605,