# HG changeset patch # User Bram Moolenaar # Date 1625773504 -7200 # Node ID 0a3b1c66d3f2a0207a35da9b2f75f26b5f441025 # Parent 60ec756f39abea9c2fb9bdcf9e88a4761852def0 patch 8.2.3129: Vim9: imported uninitialized list does not get type checked Commit: https://github.com/vim/vim/commit/c967d57aa9a6bede0f50c6986dcddc1dc035a354 Author: Bram Moolenaar Date: Thu Jul 8 21:38:50 2021 +0200 patch 8.2.3129: Vim9: imported uninitialized list does not get type checked Problem: Vim9: imported uninitialized list does not get type checked. Solution: Get type from imported variable. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -959,7 +959,7 @@ get_lval( && lp->ll_tv == &v->di_tv && ht != NULL && ht == get_script_local_ht()) { - svar_T *sv = find_typval_in_script(lp->ll_tv, TRUE); + svar_T *sv = find_typval_in_script(lp->ll_tv); // Vim9 script local variable: get the type if (sv != NULL) diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -2564,9 +2564,9 @@ eval_variable( int ret = OK; typval_T *tv = NULL; int found = FALSE; - dictitem_T *v; hashtab_T *ht = NULL; int cc; + type_T *type = NULL; // truncate the name, so that we can use strcmp() cc = name[len]; @@ -2576,13 +2576,16 @@ eval_variable( if ((tv = lookup_debug_var(name)) == NULL) { // Check for user-defined variables. - v = find_var(name, &ht, flags & EVAL_VAR_NOAUTOLOAD); + dictitem_T *v = find_var(name, &ht, flags & EVAL_VAR_NOAUTOLOAD); + if (v != NULL) { tv = &v->di_tv; if (dip != NULL) *dip = v; } + else + ht = NULL; } if (tv == NULL && (in_vim9script() || STRNCMP(name, "s:", 2) == 0)) @@ -2628,6 +2631,7 @@ eval_variable( svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + import->imp_var_vals_idx; tv = sv->sv_tv; + type = sv->sv_type; } } else if (in_vim9script()) @@ -2656,13 +2660,10 @@ eval_variable( } else if (rettv != NULL) { - type_T *type = NULL; - if (ht != NULL && ht == get_script_local_ht()) { - svar_T *sv = find_typval_in_script(tv, FALSE); - - // TODO: check imported variable + svar_T *sv = find_typval_in_script(tv); + if (sv != NULL) type = sv->sv_type; } diff --git a/src/proto/vim9script.pro b/src/proto/vim9script.pro --- a/src/proto/vim9script.pro +++ b/src/proto/vim9script.pro @@ -16,7 +16,7 @@ char_u *vim9_declare_scriptvar(exarg_T * 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); void free_all_script_vars(scriptitem_T *si); -svar_T *find_typval_in_script(typval_T *dest, int give_error); +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 : */ diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -1391,6 +1391,7 @@ def Test_import_as() vim9script export var one = 1 export var yes = 'yes' + export var slist: list END writefile(export_lines, 'XexportAs') @@ -1415,6 +1416,13 @@ def Test_import_as() END CheckScriptSuccess(import_lines) + import_lines =<< trim END + vim9script + import {slist as impSlist} from './XexportAs' + impSlist->add(123) + END + CheckScriptFailure(import_lines, 'E1012: Type mismatch; expected string but got number') + delete('XexportAs') enddef @@ -1947,8 +1955,8 @@ def Test_import_rtp() 'g:imported_rtp = exported', ] writefile(import_lines, 'Ximport_rtp.vim') - mkdir('import') - writefile(s:export_script_lines, 'import/Xexport_rtp.vim') + mkdir('Ximport') + writefile(s:export_script_lines, 'Ximport/Xexport_rtp.vim') var save_rtp = &rtp &rtp = getcwd() @@ -1960,7 +1968,7 @@ def Test_import_rtp() Undo_export_script_lines() unlet g:imported_rtp delete('Ximport_rtp.vim') - delete('import', 'rf') + delete('Ximport', 'rf') enddef def Test_import_compile_error() diff --git a/src/userfunc.c b/src/userfunc.c --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1512,7 +1512,7 @@ deref_func_name( { if (type != NULL && ht == get_script_local_ht()) { - svar_T *sv = find_typval_in_script(&v->di_tv, TRUE); + svar_T *sv = find_typval_in_script(&v->di_tv); if (sv != NULL) *type = sv->sv_type; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3129, +/**/ 3128, /**/ 3127, diff --git a/src/vim9script.c b/src/vim9script.c --- a/src/vim9script.c +++ b/src/vim9script.c @@ -616,7 +616,7 @@ handle_import( if (idx < 0 && ufunc == NULL) goto erret; - // If already imported with the same propertis and the + // If already imported with the same properties and the // IMP_FLAGS_RELOAD set then we keep that entry. Otherwise create // a new one (and give an error for an existing import). imported = find_imported(name, len, cctx); @@ -806,7 +806,7 @@ update_vim9_script_var( } else { - sv = find_typval_in_script(&di->di_tv, TRUE); + sv = find_typval_in_script(&di->di_tv); } if (sv != NULL) { @@ -922,11 +922,10 @@ free_all_script_vars(scriptitem_T *si) /* * Find the script-local variable that links to "dest". - * Returns NULL if not found and when "give_error" is TRUE this is considered - * an internal error. + * Returns NULL if not found and give an internal error. */ svar_T * -find_typval_in_script(typval_T *dest, int give_error) +find_typval_in_script(typval_T *dest) { scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); int idx; @@ -945,8 +944,7 @@ find_typval_in_script(typval_T *dest, in if (sv->sv_name != NULL && sv->sv_tv == dest) return sv; } - if (give_error) - iemsg("find_typval_in_script(): not found"); + iemsg("find_typval_in_script(): not found"); return NULL; } @@ -961,7 +959,7 @@ check_script_var_type( char_u *name, where_T where) { - svar_T *sv = find_typval_in_script(dest, TRUE); + svar_T *sv = find_typval_in_script(dest); int ret; if (sv != NULL)