Patch 8.2.2268
Problem: Vim9: list unpack seen as declaration.
Solution: Check for "var". (closes #7594)
Files: src/vim9compile.c, src/evalvars.c, src/eval.c, src/vim.h,
src/vim9execute.c, src/testdir/test_vim9_assign.vim
*** ../vim-8.2.2267/src/vim9compile.c 2021-01-01 19:17:52.297976777 +0100
--- src/vim9compile.c 2021-01-01 20:01:05.127785781 +0100
***************
*** 5634,5639 ****
--- 5634,5644 ----
semsg(_(e_cannot_use_operator_on_new_variable), name);
goto theend;
}
+ if (!is_decl)
+ {
+ semsg(_(e_unknown_variable_str), name);
+ goto theend;
+ }
// new local variable
if ((type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
***************
*** 6140,6145 ****
--- 6145,6151 ----
return NULL;
}
+ // TODO: this doesn't work for local variables
ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD, compile_unlet, cctx);
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
}
*** ../vim-8.2.2267/src/evalvars.c 2021-01-01 19:39:58.328499696 +0100
--- src/evalvars.c 2021-01-01 20:44:49.663812654 +0100
***************
*** 912,918 ****
int copy, // copy values from "tv", don't move
int semicolon, // from skip_var_list()
int var_count, // from skip_var_list()
! int flags, // ASSIGN_FINAL, ASSIGN_CONST, ASSIGN_NO_DECL
char_u *op)
{
char_u *arg = arg_start;
--- 912,918 ----
int copy, // copy values from "tv", don't move
int semicolon, // from skip_var_list()
int var_count, // from skip_var_list()
! int flags, // ASSIGN_FINAL, ASSIGN_CONST, etc.
char_u *op)
{
char_u *arg = arg_start;
***************
*** 1267,1273 ****
char_u *arg, // points to variable name
typval_T *tv, // value to assign to variable
int copy, // copy value from "tv"
! int flags, // ASSIGN_CONST, ASSIGN_FINAL, ASSIGN_NO_DECL
char_u *endchars, // valid chars after variable name or NULL
char_u *op) // "+", "-", "." or NULL
{
--- 1267,1273 ----
char_u *arg, // points to variable name
typval_T *tv, // value to assign to variable
int copy, // copy value from "tv"
! int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc.
char_u *endchars, // valid chars after variable name or NULL
char_u *op) // "+", "-", "." or NULL
{
***************
*** 1279,1285 ****
int opt_flags;
char_u *tofree = NULL;
! if (in_vim9script() && (flags & ASSIGN_NO_DECL) == 0
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
&& vim_strchr((char_u *)"$@&", *arg) != NULL)
{
--- 1279,1285 ----
int opt_flags;
char_u *tofree = NULL;
! if (in_vim9script() && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
&& vim_strchr((char_u *)"$@&", *arg) != NULL)
{
***************
*** 1476,1482 ****
lval_T lv;
p = get_lval(arg, tv, &lv, FALSE, FALSE,
! (flags & ASSIGN_NO_DECL) ? GLV_NO_DECL : 0, FNE_CHECK_START);
if (p != NULL && lv.ll_name != NULL)
{
if (endchars != NULL && vim_strchr(endchars,
--- 1476,1483 ----
lval_T lv;
p = get_lval(arg, tv, &lv, FALSE, FALSE,
! (flags & (ASSIGN_NO_DECL | ASSIGN_DECL))
! ? GLV_NO_DECL : 0, FNE_CHECK_START);
if (p != NULL && lv.ll_name != NULL)
{
if (endchars != NULL && vim_strchr(endchars,
***************
*** 3053,3059 ****
typval_T *tv,
int copy) // make copy of value in "tv"
{
! set_var_const(name, NULL, tv, copy, ASSIGN_NO_DECL);
}
/*
--- 3054,3060 ----
typval_T *tv,
int copy) // make copy of value in "tv"
{
! set_var_const(name, NULL, tv, copy, ASSIGN_DECL);
}
/*
***************
*** 3067,3073 ****
type_T *type,
typval_T *tv_arg,
int copy, // make copy of value in "tv"
! int flags) // ASSIGN_CONST, ASSIGN_FINAL, ASSIGN_NO_DECL
{
typval_T *tv = tv_arg;
typval_T bool_tv;
--- 3068,3074 ----
type_T *type,
typval_T *tv_arg,
int copy, // make copy of value in "tv"
! int flags) // ASSIGN_CONST, ASSIGN_FINAL, etc.
{
typval_T *tv = tv_arg;
typval_T bool_tv;
***************
*** 3087,3093 ****
if (vim9script
&& !is_script_local
! && (flags & ASSIGN_NO_DECL) == 0
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
&& name[1] == ':')
{
--- 3088,3094 ----
if (vim9script
&& !is_script_local
! && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
&& name[1] == ':')
{
***************
*** 3126,3132 ****
if (is_script_local && vim9script)
{
! if ((flags & ASSIGN_NO_DECL) == 0)
{
semsg(_(e_redefining_script_item_str), name);
goto failed;
--- 3127,3133 ----
if (is_script_local && vim9script)
{
! if ((flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0)
{
semsg(_(e_redefining_script_item_str), name);
goto failed;
***************
*** 3200,3207 ****
clear_tv(&di->di_tv);
}
! else // add a new variable
{
// Can't add "v:" or "a:" variable.
if (ht == &vimvarht || ht == get_funccal_args_ht())
{
--- 3201,3215 ----
clear_tv(&di->di_tv);
}
! else
{
+ // add a new variable
+ if (vim9script && is_script_local && (flags & ASSIGN_NO_DECL))
+ {
+ semsg(_(e_unknown_variable_str), name);
+ goto failed;
+ }
+
// Can't add "v:" or "a:" variable.
if (ht == &vimvarht || ht == get_funccal_args_ht())
{
*** ../vim-8.2.2267/src/eval.c 2021-01-01 19:17:52.293976798 +0100
--- src/eval.c 2021-01-01 20:40:49.080560665 +0100
***************
*** 1748,1754 ****
{
forinfo_T *fi = (forinfo_T *)fi_void;
int result;
! int flag = in_vim9script() ? ASSIGN_NO_DECL : 0;
listitem_T *item;
if (fi->fi_blob != NULL)
--- 1748,1754 ----
{
forinfo_T *fi = (forinfo_T *)fi_void;
int result;
! int flag = in_vim9script() ? ASSIGN_DECL : 0;
listitem_T *item;
if (fi->fi_blob != NULL)
*** ../vim-8.2.2267/src/vim.h 2020-12-28 15:41:37.171352372 +0100
--- src/vim.h 2021-01-01 20:40:07.376687837 +0100
***************
*** 2146,2151 ****
--- 2146,2152 ----
#define ASSIGN_FINAL 1 // ":final"
#define ASSIGN_CONST 2 // ":const"
#define ASSIGN_NO_DECL 4 // "name = expr" without ":let"/":const"/":final"
+ #define ASSIGN_DECL 8 // may declare variable if it does not exist
#include "ex_cmds.h" // Ex command defines
#include "spell.h" // spell checking stuff
*** ../vim-8.2.2267/src/vim9execute.c 2020-12-26 20:09:11.282465257 +0100
--- src/vim9execute.c 2021-01-01 20:40:15.848662073 +0100
***************
*** 806,812 ****
funccal_entry_T entry;
save_funccal(&entry);
! set_var_const(name, NULL, tv, FALSE, ASSIGN_NO_DECL);
restore_funccal();
}
--- 806,812 ----
funccal_entry_T entry;
save_funccal(&entry);
! set_var_const(name, NULL, tv, FALSE, ASSIGN_DECL);
restore_funccal();
}
*** ../vim-8.2.2267/src/testdir/test_vim9_assign.vim 2021-01-01 19:39:58.328499696 +0100
--- src/testdir/test_vim9_assign.vim 2021-01-01 20:59:25.672536373 +0100
***************
*** 262,267 ****
--- 262,273 ----
CheckDefFailure(lines, 'E1031:', 3)
lines =<< trim END
+ [v1, v2] = [1, 2]
+ END
+ CheckDefFailure(lines, 'E1089', 1)
+ CheckScriptFailure(['vim9script'] + lines, 'E1089', 2)
+
+ lines =<< trim END
var v1: number
var v2: number
[v1, v2] = ''
***************
*** 759,764 ****
--- 765,772 ----
assert_equal(5678, nr)
enddef
+ let scriptvar = 'init'
+
def Test_assignment_var_list()
var lines =<< trim END
var v1: string
***************
*** 794,803 ****
assert_equal('some', $SOME_VAR)
assert_equal('other', $OTHER_VAR)
! [g:globalvar, s:scriptvar, b:bufvar, w:winvar, t:tabvar, v:errmsg] =
! ['global', 'script', 'buf', 'win', 'tab', 'error']
assert_equal('global', g:globalvar)
- assert_equal('script', s:scriptvar)
assert_equal('buf', b:bufvar)
assert_equal('win', w:winvar)
assert_equal('tab', t:tabvar)
--- 802,810 ----
assert_equal('some', $SOME_VAR)
assert_equal('other', $OTHER_VAR)
! [g:globalvar, b:bufvar, w:winvar, t:tabvar, v:errmsg] =
! ['global', 'buf', 'win', 'tab', 'error']
assert_equal('global', g:globalvar)
assert_equal('buf', b:bufvar)
assert_equal('win', w:winvar)
assert_equal('tab', t:tabvar)
***************
*** 805,810 ****
--- 812,832 ----
unlet g:globalvar
END
CheckDefAndScriptSuccess(lines)
+
+ [g:globalvar, s:scriptvar, b:bufvar] = ['global', 'script', 'buf']
+ assert_equal('global', g:globalvar)
+ assert_equal('script', s:scriptvar)
+ assert_equal('buf', b:bufvar)
+
+ lines =<< trim END
+ vim9script
+ var s:scriptvar = 'init'
+ [g:globalvar, s:scriptvar, w:winvar] = ['global', 'script', 'win']
+ assert_equal('global', g:globalvar)
+ assert_equal('script', s:scriptvar)
+ assert_equal('win', w:winvar)
+ END
+ CheckScriptSuccess(lines)
enddef
def Test_assignment_vim9script()
***************
*** 1182,1188 ****
g:other_var = other
# type is inferred
! s:dict = {['a']: 222}
def GetDictVal(key: any)
g:dict_val = s:dict[key]
enddef
--- 1204,1210 ----
g:other_var = other
# type is inferred
! var s:dict = {['a']: 222}
def GetDictVal(key: any)
g:dict_val = s:dict[key]
enddef
*** ../vim-8.2.2267/src/version.c 2021-01-01 19:39:58.328499696 +0100
--- src/version.c 2021-01-01 20:02:32.047467331 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2268,
/**/
--
ASCII stupid question, get a stupid ANSI.
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///