0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

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.
This commit is contained in:
Bram Moolenaar
2020-09-14 18:15:09 +02:00
parent 08052228a7
commit dbeecb2b6b
4 changed files with 20 additions and 9 deletions

View File

@@ -2945,6 +2945,7 @@ set_var_const(
char_u *varname; char_u *varname;
hashtab_T *ht; hashtab_T *ht;
int is_script_local; int is_script_local;
int vim9script = in_vim9script();
ht = find_var_ht(name, &varname); ht = find_var_ht(name, &varname);
if (ht == NULL || *varname == NUL) if (ht == NULL || *varname == NUL)
@@ -2954,7 +2955,7 @@ set_var_const(
} }
is_script_local = ht == get_script_local_ht(); is_script_local = ht == get_script_local_ht();
if (in_vim9script() if (vim9script
&& !is_script_local && !is_script_local
&& (flags & LET_NO_COMMAND) == 0 && (flags & LET_NO_COMMAND) == 0
&& name[1] == ':') && name[1] == ':')
@@ -2992,7 +2993,7 @@ set_var_const(
goto failed; goto failed;
} }
if (is_script_local && in_vim9script()) if (is_script_local && vim9script)
{ {
if ((flags & LET_NO_COMMAND) == 0) if ((flags & LET_NO_COMMAND) == 0)
{ {
@@ -3088,7 +3089,7 @@ set_var_const(
if (flags & LET_IS_CONST) if (flags & LET_IS_CONST)
di->di_flags |= DI_FLAGS_LOCK; 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); scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
@@ -3123,7 +3124,8 @@ set_var_const(
init_tv(tv); 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 // Like :lockvar! name: lock the value and what it contains, but only
// if the reference count is up to one. That locks only literal // if the reference count is up to one. That locks only literal
// values. // values.

View File

@@ -821,8 +821,15 @@ enddef
def Test_const() def Test_const()
CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:') CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:') CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
CheckDefFailure(['const list = [1, 2]', 'let list = [3, 4]'], 'E1017:')
CheckDefFailure(['const two'], 'E1021:') CheckDefFailure(['const two'], 'E1021:')
CheckDefFailure(['const &option'], 'E996:') CheckDefFailure(['const &option'], 'E996:')
let lines =<< trim END
const list = [1, 2, 3]
list[0] = 4
END
CheckDefAndScriptSuccess(lines)
enddef enddef
def Test_range_no_colon() def Test_range_no_colon()

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1682,
/**/ /**/
1681, 1681,
/**/ /**/

View File

@@ -4800,11 +4800,6 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
semsg(_(e_variable_already_declared), name); semsg(_(e_variable_already_declared), name);
goto theend; goto theend;
} }
else if (lvar->lv_const)
{
semsg(_(e_cannot_assign_to_constant), name);
goto theend;
}
} }
else else
{ {
@@ -4960,6 +4955,11 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
semsg(_(e_cannot_assign_to_argument), name); semsg(_(e_cannot_assign_to_argument), name);
goto theend; goto theend;
} }
if (!is_decl && lvar != NULL && lvar->lv_const && !has_index)
{
semsg(_(e_cannot_assign_to_constant), name);
goto theend;
}
if (!heredoc) if (!heredoc)
{ {