Patch 8.2.2657
Problem: Vim9: error message for declaring variable in for loop.
Solution: Clear variables when entering block again. (closes #8012)
Files: src/ex_eval.c, src/testdir/test_vim9_script.vim
*** ../vim-8.2.2656/src/ex_eval.c 2021-03-25 22:15:24.404073755 +0100
--- src/ex_eval.c 2021-03-26 18:46:17.227975284 +0100
***************
*** 1154,1159 ****
--- 1154,1185 ----
++cstack->cs_looplevel;
cstack->cs_line[cstack->cs_idx] = -1;
}
+ else
+ {
+ if (in_vim9script() && SCRIPT_ID_VALID(current_sctx.sc_sid))
+ {
+ scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
+ int i;
+
+ // Any variables defined in the previous round are no longer
+ // visible.
+ for (i = cstack->cs_script_var_len[cstack->cs_idx];
+ i < si->sn_var_vals.ga_len; ++i)
+ {
+ svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + i;
+
+ // sv_name is set to NULL if it was already removed. This
+ // happens when it was defined in an inner block and no
+ // functions were defined there.
+ if (sv->sv_name != NULL)
+ // Remove a variable declared inside the block, if it
+ // still exists, from sn_vars.
+ hide_script_var(si, i, FALSE);
+ }
+ cstack->cs_script_var_len[cstack->cs_idx] =
+ si->sn_var_vals.ga_len;
+ }
+ }
cstack->cs_flags[cstack->cs_idx] =
eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR;
***************
*** 1175,1180 ****
--- 1201,1209 ----
void *fi;
evalarg_T evalarg;
+ /*
+ * ":for var in list-expr"
+ */
CLEAR_FIELD(evalarg);
evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE;
if (getline_equal(eap->getline, eap->cookie, getsourceline))
***************
*** 1183,1191 ****
evalarg.eval_cookie = eap->cookie;
}
- /*
- * ":for var in list-expr"
- */
if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0)
{
// Jumping here from a ":continue" or ":endfor": use the
--- 1212,1217 ----
***************
*** 1384,1393 ****
&& dbg_check_skipped(eap))
(void)do_intthrow(cstack);
! /*
! * Set loop flag, so do_cmdline() will jump back to the matching
! * ":while" or ":for".
! */
cstack->cs_lflags |= CSL_HAD_ENDLOOP;
}
}
--- 1410,1417 ----
&& dbg_check_skipped(eap))
(void)do_intthrow(cstack);
! // Set loop flag, so do_cmdline() will jump back to the matching
! // ":while" or ":for".
cstack->cs_lflags |= CSL_HAD_ENDLOOP;
}
}
*** ../vim-8.2.2656/src/testdir/test_vim9_script.vim 2021-03-18 21:37:52.196105245 +0100
--- src/testdir/test_vim9_script.vim 2021-03-26 18:42:38.320503911 +0100
***************
*** 2263,2268 ****
--- 2263,2275 ----
endfor
assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
bwipe!
+
+ var result = ''
+ for i in [1, 2, 3]
+ var loop = ' loop ' .. i
+ result ..= loop
+ endfor
+ assert_equal(' loop 1 loop 2 loop 3', result)
END
writefile(lines, 'Xvim9for.vim')
source Xvim9for.vim
*** ../vim-8.2.2656/src/version.c 2021-03-26 17:24:30.931546613 +0100
--- src/version.c 2021-03-26 18:28:18.542338482 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2657,
/**/
--
How To Keep A Healthy Level Of Insanity:
18. When leaving the zoo, start running towards the parking lot,
yelling "run for your lives, they're loose!!"
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///