Patch 8.2.2770
Problem: Vim9: type of loop variable is not used.
Solution: Parse and check the variable type. (closes #8107)
Files: src/vim9compile.c, src/testdir/test_vim9_script.vim
*** ../vim-8.2.2769/src/vim9compile.c 2021-04-15 13:42:15.914633807 +0200
--- src/vim9compile.c 2021-04-15 21:46:06.435912128 +0200
***************
*** 7514,7525 ****
return NULL;
}
! if (vartype->tt_type == VAR_LIST && vartype->tt_member->tt_type != VAR_ANY)
{
if (var_count == 1)
item_type = vartype->tt_member;
else if (vartype->tt_member->tt_type == VAR_LIST
&& vartype->tt_member->tt_member->tt_type != VAR_ANY)
item_type = vartype->tt_member->tt_member;
}
--- 7514,7529 ----
return NULL;
}
! if (vartype->tt_type == VAR_STRING)
! item_type = &t_string;
! else if (vartype->tt_type == VAR_LIST
! && vartype->tt_member->tt_type != VAR_ANY)
{
if (var_count == 1)
item_type = vartype->tt_member;
else if (vartype->tt_member->tt_type == VAR_LIST
&& vartype->tt_member->tt_member->tt_type != VAR_ANY)
+ // TODO: should get the type from
item_type = vartype->tt_member->tt_member;
}
***************
*** 7557,7568 ****
--- 7561,7579 ----
int opt_flags = 0;
int vimvaridx = -1;
type_T *type = &t_any;
+ type_T *lhs_type = &t_any;
+ where_T where;
p = skip_var_one(arg, FALSE);
varlen = p - arg;
name = vim_strnsave(arg, varlen);
if (name == NULL)
goto failed;
+ if (*p == ':')
+ {
+ p = skipwhite(p + 1);
+ lhs_type = parse_type(&p, cctx->ctx_type_list, TRUE);
+ }
// TODO: script var not supported?
if (get_var_dest(name, &dest, CMD_for, &opt_flags,
***************
*** 7589,7596 ****
}
// Reserve a variable to store "var".
! // TODO: check for type
! var_lvar = reserve_local(cctx, arg, varlen, TRUE, &t_any);
if (var_lvar == NULL)
// out of memory or used as an argument
goto failed;
--- 7600,7614 ----
}
// Reserve a variable to store "var".
! where.wt_index = var_count > 1 ? idx + 1 : 0;
! where.wt_variable = TRUE;
! if (lhs_type == &t_any)
! lhs_type = item_type;
! else if (item_type != &t_unknown
! && !(var_count > 1 && item_type == &t_any)
! && check_type(lhs_type, item_type, TRUE, where) == FAIL)
! goto failed;
! var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type);
if (var_lvar == NULL)
// out of memory or used as an argument
goto failed;
***************
*** 7602,7609 ****
generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
}
- if (*p == ':')
- p = skip_type(skipwhite(p + 1), FALSE);
if (*p == ',' || *p == ';')
++p;
arg = skipwhite(p);
--- 7620,7625 ----
*** ../vim-8.2.2769/src/testdir/test_vim9_script.vim 2021-04-14 13:30:42.974156744 +0200
--- src/testdir/test_vim9_script.vim 2021-04-15 21:48:04.999300447 +0200
***************
*** 2343,2348 ****
--- 2343,2354 ----
endfor
assert_equal(6, total)
+ var chars = ''
+ for s: string in 'foobar'
+ chars ..= s
+ endfor
+ assert_equal('foobar', chars)
+
# unpack with type
var res = ''
for [n: number, s: string] in [[1, 'a'], [2, 'b']]
***************
*** 2408,2413 ****
--- 2414,2425 ----
endfor
END
CheckDefAndScriptFailure2(lines, 'E1018:', 'E46:', 3)
+
+ lines =<< trim END
+ for nr: number in ['foo']
+ endfor
+ END
+ CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
enddef
def Test_for_loop_script_var()
*** ../vim-8.2.2769/src/version.c 2021-04-15 14:29:13.845189149 +0200
--- src/version.c 2021-04-15 21:47:06.019599335 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2770,
/**/
--
To be rich is not the end, but only a change of worries.
/// 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 ///