To: vim_dev@googlegroups.com Subject: Patch 8.2.2268 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@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 ///