patch 8.2.1682: Vim9: const works in an unexpected way
Problem: Vim9: const works in an unexpected way.
Solution: ":const" only disallows changing the variable, not the value.
Make "list[0] = 9" work at the script level.
diff --git a/src/evalvars.c b/src/evalvars.c
index f2e875c..bcc425d 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -2945,6 +2945,7 @@
char_u *varname;
hashtab_T *ht;
int is_script_local;
+ int vim9script = in_vim9script();
ht = find_var_ht(name, &varname);
if (ht == NULL || *varname == NUL)
@@ -2954,7 +2955,7 @@
}
is_script_local = ht == get_script_local_ht();
- if (in_vim9script()
+ if (vim9script
&& !is_script_local
&& (flags & LET_NO_COMMAND) == 0
&& name[1] == ':')
@@ -2992,7 +2993,7 @@
goto failed;
}
- if (is_script_local && in_vim9script())
+ if (is_script_local && vim9script)
{
if ((flags & LET_NO_COMMAND) == 0)
{
@@ -3088,7 +3089,7 @@
if (flags & LET_IS_CONST)
di->di_flags |= DI_FLAGS_LOCK;
- if (is_script_local && in_vim9script())
+ if (is_script_local && vim9script)
{
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
@@ -3123,7 +3124,8 @@
init_tv(tv);
}
- if (flags & LET_IS_CONST)
+ // ":const var = val" locks the value, but not in Vim9 script
+ if ((flags & LET_IS_CONST) && !vim9script)
// Like :lockvar! name: lock the value and what it contains, but only
// if the reference count is up to one. That locks only literal
// values.
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index c0ecad8..6358181 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -821,8 +821,15 @@
def Test_const()
CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
+ CheckDefFailure(['const list = [1, 2]', 'let list = [3, 4]'], 'E1017:')
CheckDefFailure(['const two'], 'E1021:')
CheckDefFailure(['const &option'], 'E996:')
+
+ let lines =<< trim END
+ const list = [1, 2, 3]
+ list[0] = 4
+ END
+ CheckDefAndScriptSuccess(lines)
enddef
def Test_range_no_colon()
diff --git a/src/version.c b/src/version.c
index f8d7212..d5996e9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1682,
+/**/
1681,
/**/
1680,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 8a46b2f..dd3eff4 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -4800,11 +4800,6 @@
semsg(_(e_variable_already_declared), name);
goto theend;
}
- else if (lvar->lv_const)
- {
- semsg(_(e_cannot_assign_to_constant), name);
- goto theend;
- }
}
else
{
@@ -4960,6 +4955,11 @@
semsg(_(e_cannot_assign_to_argument), name);
goto theend;
}
+ if (!is_decl && lvar != NULL && lvar->lv_const && !has_index)
+ {
+ semsg(_(e_cannot_assign_to_constant), name);
+ goto theend;
+ }
if (!heredoc)
{