summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-24 21:36:12 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-24 21:36:12 +0000
commitd787e40fdbe6f4d8bf47d36186c1d9d51c29b853 (patch)
tree7d55c1381d9d0ab309fec50c463e33b281c05d1e
parente7f4abd38b6e05100c699900c8f87281e363beb2 (diff)
downloadvim-git-d787e40fdbe6f4d8bf47d36186c1d9d51c29b853.tar.gz
patch 8.2.3890: Vim9: type check for using v: variables is basicv8.2.3890
Problem: Vim9: type check for using v: variables is basic. Solution: Specify a more precise type.
-rw-r--r--src/evalvars.c235
-rw-r--r--src/proto/evalvars.pro3
-rw-r--r--src/testdir/test_vim9_expr.vim15
-rw-r--r--src/version.c2
-rw-r--r--src/vim9instr.c3
5 files changed, 141 insertions, 117 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index 34cc014ad..adc9c204c 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -45,118 +45,119 @@ static struct vimvar
{
char *vv_name; // name of variable, without v:
dictitem16_T vv_di; // value and name for key (max 16 chars!)
+ type_T *vv_type; // type or NULL
char vv_flags; // VV_COMPAT, VV_RO, VV_RO_SBX
} vimvars[VV_LEN] =
{
// The order here must match the VV_ defines in vim.h!
// Initializing a union does not work, leave tv.vval empty to get zero's.
- {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO},
- {VV_NAME("count1", VAR_NUMBER), VV_RO},
- {VV_NAME("prevcount", VAR_NUMBER), VV_RO},
- {VV_NAME("errmsg", VAR_STRING), VV_COMPAT},
- {VV_NAME("warningmsg", VAR_STRING), 0},
- {VV_NAME("statusmsg", VAR_STRING), 0},
- {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO},
- {VV_NAME("this_session", VAR_STRING), VV_COMPAT},
- {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO},
- {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX},
- {VV_NAME("termresponse", VAR_STRING), VV_RO},
- {VV_NAME("fname", VAR_STRING), VV_RO},
- {VV_NAME("lang", VAR_STRING), VV_RO},
- {VV_NAME("lc_time", VAR_STRING), VV_RO},
- {VV_NAME("ctype", VAR_STRING), VV_RO},
- {VV_NAME("charconvert_from", VAR_STRING), VV_RO},
- {VV_NAME("charconvert_to", VAR_STRING), VV_RO},
- {VV_NAME("fname_in", VAR_STRING), VV_RO},
- {VV_NAME("fname_out", VAR_STRING), VV_RO},
- {VV_NAME("fname_new", VAR_STRING), VV_RO},
- {VV_NAME("fname_diff", VAR_STRING), VV_RO},
- {VV_NAME("cmdarg", VAR_STRING), VV_RO},
- {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX},
- {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX},
- {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX},
- {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX},
- {VV_NAME("progname", VAR_STRING), VV_RO},
- {VV_NAME("servername", VAR_STRING), VV_RO},
- {VV_NAME("dying", VAR_NUMBER), VV_RO},
- {VV_NAME("exception", VAR_STRING), VV_RO},
- {VV_NAME("throwpoint", VAR_STRING), VV_RO},
- {VV_NAME("register", VAR_STRING), VV_RO},
- {VV_NAME("cmdbang", VAR_NUMBER), VV_RO},
- {VV_NAME("insertmode", VAR_STRING), VV_RO},
- {VV_NAME("val", VAR_UNKNOWN), VV_RO},
- {VV_NAME("key", VAR_UNKNOWN), VV_RO},
- {VV_NAME("profiling", VAR_NUMBER), VV_RO},
- {VV_NAME("fcs_reason", VAR_STRING), VV_RO},
- {VV_NAME("fcs_choice", VAR_STRING), 0},
- {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO},
- {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO},
- {VV_NAME("beval_winid", VAR_NUMBER), VV_RO},
- {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO},
- {VV_NAME("beval_col", VAR_NUMBER), VV_RO},
- {VV_NAME("beval_text", VAR_STRING), VV_RO},
- {VV_NAME("scrollstart", VAR_STRING), 0},
- {VV_NAME("swapname", VAR_STRING), VV_RO},
- {VV_NAME("swapchoice", VAR_STRING), 0},
- {VV_NAME("swapcommand", VAR_STRING), VV_RO},
- {VV_NAME("char", VAR_STRING), 0},
- {VV_NAME("mouse_win", VAR_NUMBER), 0},
- {VV_NAME("mouse_winid", VAR_NUMBER), 0},
- {VV_NAME("mouse_lnum", VAR_NUMBER), 0},
- {VV_NAME("mouse_col", VAR_NUMBER), 0},
- {VV_NAME("operator", VAR_STRING), VV_RO},
- {VV_NAME("searchforward", VAR_NUMBER), 0},
- {VV_NAME("hlsearch", VAR_NUMBER), 0},
- {VV_NAME("oldfiles", VAR_LIST), 0},
- {VV_NAME("windowid", VAR_NUMBER), VV_RO},
- {VV_NAME("progpath", VAR_STRING), VV_RO},
- {VV_NAME("completed_item", VAR_DICT), VV_RO},
- {VV_NAME("option_new", VAR_STRING), VV_RO},
- {VV_NAME("option_old", VAR_STRING), VV_RO},
- {VV_NAME("option_oldlocal", VAR_STRING), VV_RO},
- {VV_NAME("option_oldglobal", VAR_STRING), VV_RO},
- {VV_NAME("option_command", VAR_STRING), VV_RO},
- {VV_NAME("option_type", VAR_STRING), VV_RO},
- {VV_NAME("errors", VAR_LIST), 0},
- {VV_NAME("false", VAR_BOOL), VV_RO},
- {VV_NAME("true", VAR_BOOL), VV_RO},
- {VV_NAME("none", VAR_SPECIAL), VV_RO},
- {VV_NAME("null", VAR_SPECIAL), VV_RO},
- {VV_NAME("numbermax", VAR_NUMBER), VV_RO},
- {VV_NAME("numbermin", VAR_NUMBER), VV_RO},
- {VV_NAME("numbersize", VAR_NUMBER), VV_RO},
- {VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO},
- {VV_NAME("testing", VAR_NUMBER), 0},
- {VV_NAME("t_number", VAR_NUMBER), VV_RO},
- {VV_NAME("t_string", VAR_NUMBER), VV_RO},
- {VV_NAME("t_func", VAR_NUMBER), VV_RO},
- {VV_NAME("t_list", VAR_NUMBER), VV_RO},
- {VV_NAME("t_dict", VAR_NUMBER), VV_RO},
- {VV_NAME("t_float", VAR_NUMBER), VV_RO},
- {VV_NAME("t_bool", VAR_NUMBER), VV_RO},
- {VV_NAME("t_none", VAR_NUMBER), VV_RO},
- {VV_NAME("t_job", VAR_NUMBER), VV_RO},
- {VV_NAME("t_channel", VAR_NUMBER), VV_RO},
- {VV_NAME("t_blob", VAR_NUMBER), VV_RO},
- {VV_NAME("termrfgresp", VAR_STRING), VV_RO},
- {VV_NAME("termrbgresp", VAR_STRING), VV_RO},
- {VV_NAME("termu7resp", VAR_STRING), VV_RO},
- {VV_NAME("termstyleresp", VAR_STRING), VV_RO},
- {VV_NAME("termblinkresp", VAR_STRING), VV_RO},
- {VV_NAME("event", VAR_DICT), VV_RO},
- {VV_NAME("versionlong", VAR_NUMBER), VV_RO},
- {VV_NAME("echospace", VAR_NUMBER), VV_RO},
- {VV_NAME("argv", VAR_LIST), VV_RO},
- {VV_NAME("collate", VAR_STRING), VV_RO},
- {VV_NAME("exiting", VAR_SPECIAL), VV_RO},
- {VV_NAME("colornames", VAR_DICT), VV_RO},
- {VV_NAME("sizeofint", VAR_NUMBER), VV_RO},
- {VV_NAME("sizeoflong", VAR_NUMBER), VV_RO},
- {VV_NAME("sizeofpointer", VAR_NUMBER), VV_RO},
+ {VV_NAME("count", VAR_NUMBER), NULL, VV_COMPAT+VV_RO},
+ {VV_NAME("count1", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("prevcount", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("errmsg", VAR_STRING), NULL, VV_COMPAT},
+ {VV_NAME("warningmsg", VAR_STRING), NULL, 0},
+ {VV_NAME("statusmsg", VAR_STRING), NULL, 0},
+ {VV_NAME("shell_error", VAR_NUMBER), NULL, VV_COMPAT+VV_RO},
+ {VV_NAME("this_session", VAR_STRING), NULL, VV_COMPAT},
+ {VV_NAME("version", VAR_NUMBER), NULL, VV_COMPAT+VV_RO},
+ {VV_NAME("lnum", VAR_NUMBER), NULL, VV_RO_SBX},
+ {VV_NAME("termresponse", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("fname", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("lang", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("lc_time", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("ctype", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("charconvert_from", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("charconvert_to", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("fname_in", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("fname_out", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("fname_new", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("fname_diff", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("cmdarg", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("foldstart", VAR_NUMBER), NULL, VV_RO_SBX},
+ {VV_NAME("foldend", VAR_NUMBER), NULL, VV_RO_SBX},
+ {VV_NAME("folddashes", VAR_STRING), NULL, VV_RO_SBX},
+ {VV_NAME("foldlevel", VAR_NUMBER), NULL, VV_RO_SBX},
+ {VV_NAME("progname", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("servername", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("dying", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("exception", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("throwpoint", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("register", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("cmdbang", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("insertmode", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("val", VAR_UNKNOWN), NULL, VV_RO},
+ {VV_NAME("key", VAR_UNKNOWN), NULL, VV_RO},
+ {VV_NAME("profiling", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("fcs_reason", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("fcs_choice", VAR_STRING), NULL, 0},
+ {VV_NAME("beval_bufnr", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("beval_winnr", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("beval_winid", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("beval_lnum", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("beval_col", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("beval_text", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("scrollstart", VAR_STRING), NULL, 0},
+ {VV_NAME("swapname", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("swapchoice", VAR_STRING), NULL, 0},
+ {VV_NAME("swapcommand", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("char", VAR_STRING), NULL, 0},
+ {VV_NAME("mouse_win", VAR_NUMBER), NULL, 0},
+ {VV_NAME("mouse_winid", VAR_NUMBER), NULL, 0},
+ {VV_NAME("mouse_lnum", VAR_NUMBER), NULL, 0},
+ {VV_NAME("mouse_col", VAR_NUMBER), NULL, 0},
+ {VV_NAME("operator", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("searchforward", VAR_NUMBER), NULL, 0},
+ {VV_NAME("hlsearch", VAR_NUMBER), NULL, 0},
+ {VV_NAME("oldfiles", VAR_LIST), &t_list_string, 0},
+ {VV_NAME("windowid", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("progpath", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("completed_item", VAR_DICT), &t_dict_string, VV_RO},
+ {VV_NAME("option_new", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("option_old", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("option_oldlocal", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("option_oldglobal", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("option_command", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("option_type", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("errors", VAR_LIST), &t_list_string, 0},
+ {VV_NAME("false", VAR_BOOL), NULL, VV_RO},
+ {VV_NAME("true", VAR_BOOL), NULL, VV_RO},
+ {VV_NAME("none", VAR_SPECIAL), NULL, VV_RO},
+ {VV_NAME("null", VAR_SPECIAL), NULL, VV_RO},
+ {VV_NAME("numbermax", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("numbermin", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("numbersize", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("vim_did_enter", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("testing", VAR_NUMBER), NULL, 0},
+ {VV_NAME("t_number", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_string", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_func", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_list", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_dict", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_float", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_bool", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_none", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_job", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_channel", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_blob", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("termrfgresp", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("termrbgresp", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("termu7resp", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("termstyleresp", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("termblinkresp", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("event", VAR_DICT), NULL, VV_RO},
+ {VV_NAME("versionlong", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("echospace", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("argv", VAR_LIST), &t_list_string, VV_RO},
+ {VV_NAME("collate", VAR_STRING), NULL, VV_RO},
+ {VV_NAME("exiting", VAR_SPECIAL), NULL, VV_RO},
+ {VV_NAME("colornames", VAR_DICT), &t_dict_string, VV_RO},
+ {VV_NAME("sizeofint", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("sizeoflong", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("sizeofpointer", VAR_NUMBER), NULL, VV_RO},
};
// shorthand
-#define vv_type vv_di.di_tv.v_type
+#define vv_tv_type vv_di.di_tv.v_type
#define vv_nr vv_di.di_tv.vval.v_number
#define vv_float vv_di.di_tv.vval.v_float
#define vv_str vv_di.di_tv.vval.v_string
@@ -214,7 +215,7 @@ evalvars_init(void)
p->vv_di.di_flags = DI_FLAGS_FIX;
// add to v: scope dict, unless the value is not always available
- if (p->vv_type != VAR_UNKNOWN)
+ if (p->vv_tv_type != VAR_UNKNOWN)
hash_add(&vimvarht, p->vv_di.di_key);
if (p->vv_flags & VV_COMPAT)
// add to compat scope dict
@@ -510,7 +511,7 @@ prepare_vimvar(int idx, typval_T *save_tv)
{
*save_tv = vimvars[idx].vv_tv;
vimvars[idx].vv_str = NULL; // don't free it now
- if (vimvars[idx].vv_type == VAR_UNKNOWN)
+ if (vimvars[idx].vv_tv_type == VAR_UNKNOWN)
hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
}
@@ -525,7 +526,7 @@ restore_vimvar(int idx, typval_T *save_tv)
hashitem_T *hi;
vimvars[idx].vv_tv = *save_tv;
- if (vimvars[idx].vv_type == VAR_UNKNOWN)
+ if (vimvars[idx].vv_tv_type == VAR_UNKNOWN)
{
hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
if (HASHITEM_EMPTY(hi))
@@ -2265,7 +2266,7 @@ find_vim_var(char_u *name, int *di_flags)
void
set_vim_var_type(int idx, vartype_T type)
{
- vimvars[idx].vv_type = type;
+ vimvars[idx].vv_tv_type = type;
}
/*
@@ -2293,6 +2294,14 @@ get_vim_var_tv(int idx)
return &vimvars[idx].vv_tv;
}
+ type_T *
+get_vim_var_type(int idx, garray_T *type_list)
+{
+ if (vimvars[idx].vv_type != NULL)
+ return vimvars[idx].vv_type;
+ return typval2type_vimvar(&vimvars[idx].vv_tv, type_list);
+}
+
/*
* Set v: variable to "tv". Only accepts the same type.
* Takes over the value of "tv".
@@ -2300,7 +2309,7 @@ get_vim_var_tv(int idx)
int
set_vim_var_tv(int idx, typval_T *tv)
{
- if (vimvars[idx].vv_type != tv->v_type)
+ if (vimvars[idx].vv_tv_type != tv->v_type)
{
emsg(_(e_type_mismatch_for_v_variable));
clear_tv(tv);
@@ -2430,7 +2439,7 @@ set_vim_var_string(
int len) // length of "val" to use or -1 (whole string)
{
clear_tv(&vimvars[idx].vv_di.di_tv);
- vimvars[idx].vv_type = VAR_STRING;
+ vimvars[idx].vv_tv_type = VAR_STRING;
if (val == NULL)
vimvars[idx].vv_str = NULL;
else if (len == -1)
@@ -2446,7 +2455,7 @@ set_vim_var_string(
set_vim_var_list(int idx, list_T *val)
{
clear_tv(&vimvars[idx].vv_di.di_tv);
- vimvars[idx].vv_type = VAR_LIST;
+ vimvars[idx].vv_tv_type = VAR_LIST;
vimvars[idx].vv_list = val;
if (val != NULL)
++val->lv_refcount;
@@ -2459,7 +2468,7 @@ set_vim_var_list(int idx, list_T *val)
set_vim_var_dict(int idx, dict_T *val)
{
clear_tv(&vimvars[idx].vv_di.di_tv);
- vimvars[idx].vv_type = VAR_DICT;
+ vimvars[idx].vv_tv_type = VAR_DICT;
vimvars[idx].vv_dict = val;
if (val != NULL)
{
@@ -3925,7 +3934,7 @@ assert_error(garray_T *gap)
{
struct vimvar *vp = &vimvars[VV_ERRORS];
- if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
+ if (vp->vv_tv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
// Make sure v:errors is a list.
set_vim_var_list(VV_ERRORS, list_alloc());
list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro
index 778506f88..9fb2c77b5 100644
--- a/src/proto/evalvars.pro
+++ b/src/proto/evalvars.pro
@@ -38,6 +38,7 @@ void set_vim_var_type(int idx, vartype_T type);
void set_vim_var_nr(int idx, varnumber_T val);
char *get_vim_var_name(int idx);
typval_T *get_vim_var_tv(int idx);
+type_T *get_vim_var_type(int idx, garray_T *type_list);
int set_vim_var_tv(int idx, typval_T *tv);
varnumber_T get_vim_var_nr(int idx);
char_u *get_vim_var_str(int idx);
@@ -71,7 +72,7 @@ void vars_clear(hashtab_T *ht);
void vars_clear_ext(hashtab_T *ht, int free_val);
void delete_var(hashtab_T *ht, hashitem_T *hi);
void set_var(char_u *name, typval_T *tv, int copy);
-void set_var_const(char_u *name, type_T *type, typval_T *tv_arg, int copy, int flags_arg, int var_idx);
+void set_var_const(char_u *name, type_T *type_arg, typval_T *tv_arg, int copy, int flags_arg, int var_idx);
int var_check_permission(dictitem_T *di, char_u *name);
int var_check_ro(int flags, char_u *name, int use_gettext);
int var_check_lock(int flags, char_u *name, int use_gettext);
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index 259d7722b..9cf035a61 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -1821,8 +1821,21 @@ def Test_expr7_string()
enddef
def Test_expr7_vimvar()
+ v:errors = []
+ var errs: list<string> = v:errors
+ CheckDefFailure(['var errs: list<number> = v:errors'], 'E1012:')
+
var old: list<string> = v:oldfiles
- var compl: dict<any> = v:completed_item
+ CheckDefFailure(['var old: list<number> = v:oldfiles'], 'E1012:')
+
+ var compl: dict<string> = v:completed_item
+ CheckDefFailure(['var compl: dict<number> = v:completed_item'], 'E1012:')
+
+ var args: list<string> = v:argv
+ CheckDefFailure(['var args: list<number> = v:argv'], 'E1012:')
+
+ var colors: dict<string> = v:colornames
+ CheckDefFailure(['var colors: dict<number> = v:colornames'], 'E1012:')
CheckDefFailure(["var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 1)
CheckScriptFailure(['vim9script', 'v:oldfiles = ["foo"]', "var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 3)
diff --git a/src/version.c b/src/version.c
index cd4d15775..dd99a31d3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3890,
+/**/
3889,
/**/
3888,
diff --git a/src/vim9instr.c b/src/vim9instr.c
index 06d6b9004..0468f336c 100644
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -946,8 +946,7 @@ generate_LOADV(
semsg(_(e_variable_not_found_str), name);
return FAIL;
}
- type = typval2type_vimvar(get_vim_var_tv(vidx), cctx->ctx_type_list);
-
+ type = get_vim_var_type(vidx, cctx->ctx_type_list);
return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, type);
}