]> granicus.if.org Git - vim/commitdiff
patch 8.2.1682: Vim9: const works in an unexpected way v8.2.1682
authorBram Moolenaar <Bram@vim.org>
Mon, 14 Sep 2020 16:15:09 +0000 (18:15 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 14 Sep 2020 16:15:09 +0000 (18:15 +0200)
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.

src/evalvars.c
src/testdir/test_vim9_script.vim
src/version.c
src/vim9compile.c

index f2e875cc8ab83f2f41955f769a16591d967deb49..bcc425da5ab19ce8c1538e2c3dd675056b78b3a6 100644 (file)
@@ -2945,6 +2945,7 @@ set_var_const(
     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 @@ set_var_const(
     }
     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 @@ set_var_const(
                goto failed;
            }
 
-           if (is_script_local && in_vim9script())
+           if (is_script_local && vim9script)
            {
                if ((flags & LET_NO_COMMAND) == 0)
                {
@@ -3088,7 +3089,7 @@ set_var_const(
        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 @@ set_var_const(
        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.
index c0ecad80362962f96bca4d91126d702baed8e4bb..63581818e951b726b953818664aa86d2ad828e13 100644 (file)
@@ -821,8 +821,15 @@ enddef
 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()
index f8d72126ab39b8d9097fcf7ce398141a0a597478..d5996e9571fe46a1aa176c7df10467da921620b4 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1682,
 /**/
     1681,
 /**/
index 8a46b2f77737e2cac325b0e035636ed9711f9ad5..dd3eff49cd303c8bd56a0875f608e9994e87e016 100644 (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);
                        goto theend;
                    }
-                   else if (lvar->lv_const)
-                   {
-                       semsg(_(e_cannot_assign_to_constant), name);
-                       goto theend;
-                   }
                }
                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);
            goto theend;
        }
+       if (!is_decl && lvar != NULL && lvar->lv_const && !has_index)
+       {
+           semsg(_(e_cannot_assign_to_constant), name);
+           goto theend;
+       }
 
        if (!heredoc)
        {