patch 7.4.2137
Problem: Using function() with a name will find another function when it is
redefined.
Solution: Add funcref(). Refer to lambda using a partial. Fix several
reference counting issues.
diff --git a/src/eval.c b/src/eval.c
index cf2c771..495bbb0 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5011,6 +5011,17 @@
return OK;
}
+/*
+ * Return the function name of the partial.
+ */
+ char_u *
+partial_name(partial_T *pt)
+{
+ if (pt->pt_name != NULL)
+ return pt->pt_name;
+ return pt->pt_func->uf_name;
+}
+
static void
partial_free(partial_T *pt)
{
@@ -5020,8 +5031,13 @@
clear_tv(&pt->pt_argv[i]);
vim_free(pt->pt_argv);
dict_unref(pt->pt_dict);
- func_unref(pt->pt_name);
- vim_free(pt->pt_name);
+ if (pt->pt_name != NULL)
+ {
+ func_unref(pt->pt_name);
+ vim_free(pt->pt_name);
+ }
+ else
+ func_ptr_unref(pt->pt_func);
vim_free(pt);
}
@@ -5051,11 +5067,11 @@
/* empty and NULL function name considered the same */
s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
- : tv1->vval.v_partial->pt_name;
+ : partial_name(tv1->vval.v_partial);
if (s1 != NULL && *s1 == NUL)
s1 = NULL;
s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
- : tv2->vval.v_partial->pt_name;
+ : partial_name(tv2->vval.v_partial);
if (s2 != NULL && *s2 == NUL)
s2 = NULL;
if (s1 == NULL || s2 == NULL)
@@ -5550,7 +5566,7 @@
}
else if (tv->v_type == VAR_FUNC)
{
- abort = set_ref_in_func(tv->vval.v_string, copyID);
+ abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
}
else if (tv->v_type == VAR_PARTIAL)
{
@@ -5561,7 +5577,7 @@
*/
if (pt != NULL)
{
- abort = set_ref_in_func(pt->pt_name, copyID);
+ abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
if (pt->pt_dict != NULL)
{
@@ -5735,7 +5751,7 @@
{
partial_T *pt = tv->vval.v_partial;
char_u *fname = string_quote(pt == NULL ? NULL
- : pt->pt_name, FALSE);
+ : partial_name(pt), FALSE);
garray_T ga;
int i;
char_u *tf;
@@ -6871,7 +6887,7 @@
if (functv.v_type == VAR_PARTIAL)
{
pt = functv.vval.v_partial;
- s = pt->pt_name;
+ s = partial_name(pt);
}
else
s = functv.vval.v_string;
@@ -10025,7 +10041,7 @@
{
partial_T *partial = expr->vval.v_partial;
- s = partial->pt_name;
+ s = partial_name(partial);
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
goto theend;