To: vim_dev@googlegroups.com Subject: Patch 8.2.3682 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3682 Problem: Vim9: assigning to a script variable drops the required type. Solution: Lookup the type of the variable and use it. (closes #9219) Files: src/evalvars.c, src/vim9script.c, src/proto/vim9script.pro, src/testdir/test_vim9_assign.vim *** ../vim-8.2.3681/src/evalvars.c 2021-11-22 21:58:37.918668436 +0000 --- src/evalvars.c 2021-11-26 17:35:30.548872169 +0000 *************** *** 3206,3218 **** void set_var_const( char_u *name, ! type_T *type, typval_T *tv_arg, int copy, // make copy of value in "tv" int flags_arg, // ASSIGN_CONST, ASSIGN_FINAL, etc. int var_idx) // index for ":let [a, b] = list" { typval_T *tv = tv_arg; typval_T bool_tv; dictitem_T *di; typval_T *dest_tv = NULL; --- 3206,3219 ---- void set_var_const( char_u *name, ! type_T *type_arg, typval_T *tv_arg, int copy, // make copy of value in "tv" int flags_arg, // ASSIGN_CONST, ASSIGN_FINAL, etc. int var_idx) // index for ":let [a, b] = list" { typval_T *tv = tv_arg; + type_T *type = type_arg; typval_T bool_tv; dictitem_T *di; typval_T *dest_tv = NULL; *************** *** 3334,3346 **** if (var_in_vim9script && (flags & ASSIGN_FOR_LOOP) == 0) { where_T where = WHERE_INIT; ! // check the type and adjust to bool if needed ! where.wt_index = var_idx; ! where.wt_variable = TRUE; ! if (check_script_var_type(&di->di_tv, tv, name, where) ! == FAIL) ! goto failed; } if ((flags & ASSIGN_FOR_LOOP) == 0 --- 3335,3352 ---- if (var_in_vim9script && (flags & ASSIGN_FOR_LOOP) == 0) { where_T where = WHERE_INIT; + svar_T *sv = find_typval_in_script(&di->di_tv); ! if (sv != NULL) ! { ! // check the type and adjust to bool if needed ! where.wt_index = var_idx; ! where.wt_variable = TRUE; ! if (check_script_var_type(sv, tv, name, where) == FAIL) ! goto failed; ! if (type == NULL) ! type = sv->sv_type; ! } } if ((flags & ASSIGN_FOR_LOOP) == 0 *** ../vim-8.2.3681/src/vim9script.c 2021-10-15 00:18:32.890481145 +0100 --- src/vim9script.c 2021-11-26 17:29:27.141126221 +0000 *************** *** 999,1033 **** */ int check_script_var_type( ! typval_T *dest, typval_T *value, char_u *name, where_T where) { - svar_T *sv = find_typval_in_script(dest); int ret; ! if (sv != NULL) { ! if (sv->sv_const != 0) ! { ! semsg(_(e_cannot_change_readonly_variable_str), name); ! return FAIL; ! } ! ret = check_typval_type(sv->sv_type, value, where); ! if (ret == OK && need_convert_to_bool(sv->sv_type, value)) ! { ! int val = tv2bool(value); ! ! clear_tv(value); ! value->v_type = VAR_BOOL; ! value->v_lock = 0; ! value->vval.v_number = val ? VVAL_TRUE : VVAL_FALSE; ! } ! return ret; } ! return OK; // not really } // words that cannot be used as a variable --- 999,1027 ---- */ int check_script_var_type( ! svar_T *sv, typval_T *value, char_u *name, where_T where) { int ret; ! if (sv->sv_const != 0) { ! semsg(_(e_cannot_change_readonly_variable_str), name); ! return FAIL; } + ret = check_typval_type(sv->sv_type, value, where); + if (ret == OK && need_convert_to_bool(sv->sv_type, value)) + { + int val = tv2bool(value); ! clear_tv(value); ! value->v_type = VAR_BOOL; ! value->v_lock = 0; ! value->vval.v_number = val ? VVAL_TRUE : VVAL_FALSE; ! } ! return ret; } // words that cannot be used as a variable *** ../vim-8.2.3681/src/proto/vim9script.pro 2021-08-15 12:49:38.122905579 +0100 --- src/proto/vim9script.pro 2021-11-26 17:30:54.705081599 +0000 *************** *** 16,21 **** void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T *tv, type_T **type, int do_member); void hide_script_var(scriptitem_T *si, int idx, int func_defined); svar_T *find_typval_in_script(typval_T *dest); ! int check_script_var_type(typval_T *dest, typval_T *value, char_u *name, where_T where); int check_reserved_name(char_u *name); /* vim: set ft=c : */ --- 16,21 ---- void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T *tv, type_T **type, int do_member); void hide_script_var(scriptitem_T *si, int idx, int func_defined); svar_T *find_typval_in_script(typval_T *dest); ! int check_script_var_type(svar_T *sv, typval_T *value, char_u *name, where_T where); int check_reserved_name(char_u *name); /* vim: set ft=c : */ *** ../vim-8.2.3681/src/testdir/test_vim9_assign.vim 2021-09-09 22:01:10.506519642 +0100 --- src/testdir/test_vim9_assign.vim 2021-11-26 17:34:44.768912804 +0000 *************** *** 322,327 **** --- 322,337 ---- CheckDefAndScriptSuccess(lines) enddef + def Test_assign_keep_type() + var lines =<< trim END + vim9script + var l: list = [123] + l = [123] + l->add('string') + END + CheckScriptFailure(lines, 'E1012:', 4) + enddef + def Test_assign_unpack() var lines =<< trim END var v1: number *** ../vim-8.2.3681/src/version.c 2021-11-26 15:57:14.310265430 +0000 --- src/version.c 2021-11-26 17:27:27.769164014 +0000 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 3682, /**/ -- Why is "abbreviation" such a long word? /// Bram Moolenaar -- Bram@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 ///