To: vim_dev@googlegroups.com Subject: Patch 8.2.1338 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1338 Problem: Vim9: assigning to script-local variable doesn't check type. Solution: Use the type. (issue #6591) Files: src/vim9compile.c, src/vim9execute.c, src/testdir/test_vim9_script.vim *** ../vim-8.2.1337/src/vim9compile.c 2020-07-31 23:47:08.017231395 +0200 --- src/vim9compile.c 2020-08-01 15:09:47.552979401 +0200 *************** *** 5070,5075 **** --- 5070,5077 ---- char_u *ret = NULL; int var_count = 0; int var_idx; + int scriptvar_sid = 0; + int scriptvar_idx = -1; int semicolon = 0; garray_T *instr = &cctx->ctx_instr; garray_T *stack = &cctx->ctx_type_stack; *************** *** 5333,5339 **** } else { ! int idx; for (idx = 0; reserved[idx] != NULL; ++idx) if (STRCMP(reserved[idx], name) == 0) --- 5335,5342 ---- } else { ! int idx; ! imported_T *import = NULL; for (idx = 0; reserved[idx] != NULL; ++idx) if (STRCMP(reserved[idx], name) == 0) *************** *** 5374,5382 **** } else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0) || lookup_script(var_start, varlen) == OK ! || find_imported(var_start, varlen, cctx) != NULL) { ! dest = dest_script; if (is_decl) { if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)) --- 5377,5387 ---- } else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0) || lookup_script(var_start, varlen) == OK ! || (import = find_imported(var_start, varlen, cctx)) ! != NULL) { ! char_u *rawname = name + (name[1] == ':' ? 2 : 0); ! if (is_decl) { if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)) *************** *** 5387,5392 **** --- 5392,5412 ---- name); goto theend; } + dest = dest_script; + + // existing script-local variables should have a type + scriptvar_sid = current_sctx.sc_sid; + if (import != NULL) + scriptvar_sid = import->imp_sid; + scriptvar_idx = get_script_item_idx(scriptvar_sid, + rawname, TRUE); + if (scriptvar_idx >= 0) + { + scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid); + svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + + scriptvar_idx; + type = sv->sv_type; + } } else if (name[1] == ':' && name[2] != NUL) { *************** *** 5766,5786 **** break; case dest_script: { ! char_u *rawname = name + (name[1] == ':' ? 2 : 0); ! imported_T *import = NULL; ! int sid = current_sctx.sc_sid; ! int idx; ! ! if (name[1] != ':') ! { ! import = find_imported(name, 0, cctx); ! if (import != NULL) ! sid = import->imp_sid; ! } ! ! idx = get_script_item_idx(sid, rawname, TRUE); ! // TODO: specific type ! if (idx < 0) { char_u *name_s = name; --- 5786,5792 ---- break; case dest_script: { ! if (scriptvar_idx < 0) { char_u *name_s = name; *************** *** 5796,5809 **** vim_snprintf((char *)name_s, len, "s:%s", name); } ! generate_OLDSCRIPT(cctx, ISN_STORES, name_s, sid, ! &t_any); if (name_s != name) vim_free(name_s); } else generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT, ! sid, idx, &t_any); } break; case dest_local: --- 5802,5815 ---- vim_snprintf((char *)name_s, len, "s:%s", name); } ! generate_OLDSCRIPT(cctx, ISN_STORES, name_s, ! scriptvar_sid, type); if (name_s != name) vim_free(name_s); } else generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT, ! scriptvar_sid, scriptvar_idx, type); } break; case dest_local: *** ../vim-8.2.1337/src/vim9execute.c 2020-08-01 14:06:34.837676926 +0200 --- src/vim9execute.c 2020-08-01 15:20:37.402307457 +0200 *************** *** 1422,1427 **** --- 1422,1432 ---- dict_T *dict = tv_dict->vval.v_dict; dictitem_T *di; + if (dict == NULL) + { + emsg(_(e_dictnull)); + goto on_error; + } if (key == NULL) key = (char_u *)""; tv = STACK_TV_BOT(-3); *** ../vim-8.2.1337/src/testdir/test_vim9_script.vim 2020-08-01 14:06:34.837676926 +0200 --- src/testdir/test_vim9_script.vim 2020-08-01 15:34:28.334683029 +0200 *************** *** 251,256 **** --- 251,279 ---- # type becomes dict let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'} + + # assignment to script-local dict + let lines =<< trim END + vim9script + let test: dict = {} + def FillDict(): dict + test['a'] = 43 + return test + enddef + assert_equal(#{a: 43}, FillDict()) + END + call CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + let test: dict + def FillDict(): dict + test['a'] = 43 + return test + enddef + FillDict() + END + call CheckScriptFailure(lines, 'E1103:') enddef def Test_assignment_local() *** ../vim-8.2.1337/src/version.c 2020-08-01 14:06:34.837676926 +0200 --- src/version.c 2020-08-01 15:04:53.794079795 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1338, /**/ -- hundred-and-one symptoms of being an internet addict: 92. It takes you two hours to check all 14 of your mailboxes. /// 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 ///