patch 9.2.1008: Vim9: hang when a line break is used before "->("

Problem:  In Vim9 script a line break before "->(" makes Vim hang and
          use up memory (SectionCotangentBundle)
Solution: Consume the line break for "->(" as well, and skip white
          space after "->" in a compiled function too (Hirohito Higashi).

fixes:  #21144
closes: #21147

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Hirohito HigashiandClaude Opus 5 authored and Christian Brabandt committed 2026-08-25 20:18:37 +00:00
1 parent 7e74722999
commit 4b0b53e856
4 files changed
+28 -5

No files matched your search

+17 -4
View File
@@ -7591,6 +7591,21 @@ eval_isdictc(int c)
return ASCII_ISALNUM(c) || c == '_';
}
/*
* Return true when "p" points to "->" followed by a method name or a lambda.
* Only called for Vim9 script.
*/
static bool
method_call_follows(char_u *p)
{
if (p[0] != '-' || p[1] != '>')
return false;
char_u *after = skipwhite(p + 2);
return ASCII_ISALPHA(*after) || *after == '(';
}
/*
* Handle:
* - expr[expr], expr[expr:expr] subscript
@@ -7619,7 +7634,7 @@ handle_subscript(
while (ret == OK)
{
// When at the end of the line and ".name" or "->{" or "->X" follows in
// When at the end of the line and ".name" or a method call follows in
// the next line then consume the line break.
p = eval_next_non_blank(*arg, evalarg, &getnext);
if (getnext
@@ -7627,9 +7642,7 @@ handle_subscript(
&& ((rettv->v_type == VAR_DICT && eval_isdictc(p[1]))
|| rettv->v_type == VAR_CLASS
|| rettv->v_type == VAR_OBJECT))
|| (p[0] == '-' && p[1] == '>' && (p[2] == '{'
|| ASCII_ISALPHA(in_vim9script() ? *skipwhite(p + 2)
: p[2])))))
|| method_call_follows(p)))
{
*arg = eval_next_line(*arg, evalarg);
p = *arg;
+8
View File
@@ -3964,6 +3964,14 @@ def Test_expr9_method_call()
var sorted = [3, 1, 2]
-> sort()
assert_equal([1, 2, 3], sorted)
var nrs = [1, 2]
->((x) => x)()
assert_equal([1, 2], nrs)
nrs = [3, 4]
-> ((x) => x)()
assert_equal([3, 4], nrs)
END
v9.CheckDefAndScriptSuccess(lines)
+2
View File
@@ -763,6 +763,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1008,
/**/
1007,
/**/
+1 -1
View File
@@ -2550,7 +2550,7 @@ compile_subscript(
if (next != NULL &&
((next[0] == '-' && next[1] == '>'
&& (next[2] == '{'
|| next[2] == '('
|| *skipwhite(next + 2) == '('
|| ASCII_ISALPHA(*skipwhite(next + 2))))
|| (next[0] == '.' && eval_isdictc(next[1]))))
{