patch 9.1.2121: Vim9: type issue when modifying a variable using :legacy
Commit:
https://github.com/vim/vim/commit/f5466b5a73686e55445600a06adbf6363c474a2b
Author: Yegappan Lakshmanan <
yega...@yahoo.com>
Date: Sat Jan 31 10:07:02 2026 +0000
patch 9.1.2121: Vim9: type issue when modifying a variable using :legacy
Problem: Vim9: type issue when modifying a variable using :legacy
(kennypete)
Solution: In a vim9 script, when modifying a variable using the legacy
command, check the type (Yegappan Lakshmanan).
fixes: #18531
closes: #19292
Signed-off-by: Yegappan Lakshmanan <
yega...@yahoo.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/eval.c b/src/eval.c
index 9678ea7f6..d2f06fd11 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1860,7 +1860,6 @@ get_lval_subscript(
int flags, // GLV_ values
class_T *cl_exec)
{
- int vim9script = in_vim9script();
int quiet = flags & GLV_QUIET;
char_u *key = NULL;
int len;
@@ -1908,7 +1907,7 @@ get_lval_subscript(
vartype_name(v_type));
#endif
- if (vim9script && lp->ll_valtype == NULL
+ if (current_script_is_vim9() && lp->ll_valtype == NULL
&& v != NULL
&& lp->ll_tv == &v->di_tv
&& ht != NULL && ht == get_script_local_ht())
@@ -2468,7 +2467,10 @@ set_var_lval(
if (lp->ll_valtype != NULL
&& check_typval_arg_type(lp->ll_valtype, rettv,
NULL, 0) == FAIL)
+ {
+ lp->ll_name_end = NULL;
return;
+ }
// If the lval is a List and the type of the list is not yet set,
// then set the item type from the declared type of the variable.
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index a8c6c01cb..b915b666d 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -2563,6 +2563,52 @@ def Test_var_type_check()
defcompile
END
v9.CheckScriptSuccess(lines)
+
+ # Modifying a variable type using the legacy command at script level
+ lines =<< trim END
+ vim9script
+ var l: list<number> = [1, 2]
+ legacy let s:l[0] = 'x'
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 3)
+
+ # try with dict type
+ lines =<< trim END
+ vim9script
+ var d: dict<number>
+ legacy let s:d['a'] = 'x'
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 3)
+
+ # Modifying a variable type using the legacy command in a def function
+ lines =<< trim END
+ vim9script
+ var l: list<number> = [1, 2]
+ def Fn()
+ legacy let s:l[0] = 'x'
+ enddef
+ Fn()
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
+
+ # try with dict type
+ lines =<< trim END
+ vim9script
+ var d: dict<string>
+ def Fn()
+ legacy let s:d['a'] = 10
+ enddef
+ Fn()
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
+
+ # after the first error, the assignment should be aborted
+ lines =<< trim END
+ vim9script
+ var l: list<number> = [1, 2]
+ legacy let [s:l[0], s:l[1]] = ['x', 1.0]
+ END
+ v9.CheckSourceFailureList(lines, ['', 'E1012: Type mismatch; expected number but got string'], 3)
enddef
let g:dict_number = #{one: 1, two: 2}
diff --git a/src/version.c b/src/version.c
index 94b463ebe..827956351 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 2121,
/**/
2120,
/**/