Skip to content

Commit 522eefd

Browse files
committed
patch 8.2.2657: Vim9: error message for declaring variable in for loop
Problem: Vim9: error message for declaring variable in for loop. Solution: Clear variables when entering block again. (closes #8012)
1 parent a2b3e7d commit 522eefd

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

src/ex_eval.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,32 @@ ex_while(exarg_T *eap)
11541154
++cstack->cs_looplevel;
11551155
cstack->cs_line[cstack->cs_idx] = -1;
11561156
}
1157+
else
1158+
{
1159+
if (in_vim9script() && SCRIPT_ID_VALID(current_sctx.sc_sid))
1160+
{
1161+
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
1162+
int i;
1163+
1164+
// Any variables defined in the previous round are no longer
1165+
// visible.
1166+
for (i = cstack->cs_script_var_len[cstack->cs_idx];
1167+
i < si->sn_var_vals.ga_len; ++i)
1168+
{
1169+
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + i;
1170+
1171+
// sv_name is set to NULL if it was already removed. This
1172+
// happens when it was defined in an inner block and no
1173+
// functions were defined there.
1174+
if (sv->sv_name != NULL)
1175+
// Remove a variable declared inside the block, if it
1176+
// still exists, from sn_vars.
1177+
hide_script_var(si, i, FALSE);
1178+
}
1179+
cstack->cs_script_var_len[cstack->cs_idx] =
1180+
si->sn_var_vals.ga_len;
1181+
}
1182+
}
11571183
cstack->cs_flags[cstack->cs_idx] =
11581184
eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR;
11591185

@@ -1175,6 +1201,9 @@ ex_while(exarg_T *eap)
11751201
void *fi;
11761202
evalarg_T evalarg;
11771203

1204+
/*
1205+
* ":for var in list-expr"
1206+
*/
11781207
CLEAR_FIELD(evalarg);
11791208
evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE;
11801209
if (getline_equal(eap->getline, eap->cookie, getsourceline))
@@ -1183,9 +1212,6 @@ ex_while(exarg_T *eap)
11831212
evalarg.eval_cookie = eap->cookie;
11841213
}
11851214

1186-
/*
1187-
* ":for var in list-expr"
1188-
*/
11891215
if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0)
11901216
{
11911217
// Jumping here from a ":continue" or ":endfor": use the
@@ -1384,10 +1410,8 @@ ex_endwhile(exarg_T *eap)
13841410
&& dbg_check_skipped(eap))
13851411
(void)do_intthrow(cstack);
13861412

1387-
/*
1388-
* Set loop flag, so do_cmdline() will jump back to the matching
1389-
* ":while" or ":for".
1390-
*/
1413+
// Set loop flag, so do_cmdline() will jump back to the matching
1414+
// ":while" or ":for".
13911415
cstack->cs_lflags |= CSL_HAD_ENDLOOP;
13921416
}
13931417
}

src/testdir/test_vim9_script.vim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,13 @@ def Test_for_outside_of_function()
22632263
endfor
22642264
assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
22652265
bwipe!
2266+
2267+
var result = ''
2268+
for i in [1, 2, 3]
2269+
var loop = ' loop ' .. i
2270+
result ..= loop
2271+
endfor
2272+
assert_equal(' loop 1 loop 2 loop 3', result)
22662273
END
22672274
writefile(lines, 'Xvim9for.vim')
22682275
source Xvim9for.vim

src/version.c

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

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2657,
753755
/**/
754756
2656,
755757
/**/

0 commit comments

Comments
 (0)