diff src/evalvars.c @ 22272:eb1f5f618c75 v8.2.1685

patch 8.2.1685: Vim9: cannot declare a constant value Commit: https://github.com/vim/vim/commit/0b4c66c67a083f25816b9cdb8e76a41e02d9f560 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Sep 14 21:39:44 2020 +0200 patch 8.2.1685: Vim9: cannot declare a constant value Problem: Vim9: cannot declare a constant value. Solution: Introduce ":const!".
author Bram Moolenaar <Bram@vim.org>
date Mon, 14 Sep 2020 21:45:04 +0200
parents 23f5750146d9
children 07e48ee8c3bb
line wrap: on
line diff
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -173,7 +173,6 @@ static char_u *list_arg_vars(exarg_T *ea
 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags, char_u *endchars, char_u *op);
 static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie);
 static int do_lock_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie);
-static void item_lock(typval_T *tv, int deep, int lock, int check_refcount);
 static void delete_var(hashtab_T *ht, hashitem_T *hi);
 static void list_one_var(dictitem_T *v, char *prefix, int *first);
 static void list_one_var_a(char *prefix, char_u *name, int type, char_u *string, int *first);
@@ -709,6 +708,8 @@ ex_let(exarg_T *eap)
     // detect Vim9 assignment without ":let" or ":const"
     if (eap->arg == eap->cmd)
 	flags |= LET_NO_COMMAND;
+    if (eap->forceit)
+	flags |= LET_FORCEIT;
 
     argend = skip_var_list(arg, TRUE, &var_count, &semicolon, FALSE);
     if (argend == NULL)
@@ -859,7 +860,7 @@ ex_let_vars(
     int		copy,		// copy values from "tv", don't move
     int		semicolon,	// from skip_var_list()
     int		var_count,	// from skip_var_list()
-    int		flags,		// LET_IS_CONST and/or LET_NO_COMMAND
+    int		flags,		// LET_IS_CONST, LET_FORCEIT, LET_NO_COMMAND
     char_u	*op)
 {
     char_u	*arg = arg_start;
@@ -1214,7 +1215,7 @@ ex_let_one(
     char_u	*arg,		// points to variable name
     typval_T	*tv,		// value to assign to variable
     int		copy,		// copy value from "tv"
-    int		flags,		// LET_IS_CONST and/or LET_NO_COMMAND
+    int		flags,		// LET_IS_CONST, LET_FORCEIT, LET_NO_COMMAND
     char_u	*endchars,	// valid chars after variable name  or NULL
     char_u	*op)		// "+", "-", "."  or NULL
 {
@@ -1741,7 +1742,7 @@ do_lock_var(
  * When "check_refcount" is TRUE do not lock a list or dict with a reference
  * count larger than 1.
  */
-    static void
+    void
 item_lock(typval_T *tv, int deep, int lock, int check_refcount)
 {
     static int	recurse = 0;
@@ -2937,7 +2938,7 @@ set_var_const(
     type_T	*type,
     typval_T	*tv_arg,
     int		copy,	    // make copy of value in "tv"
-    int		flags)	    // LET_IS_CONST and/or LET_NO_COMMAND
+    int		flags)	    // LET_IS_CONST, LET_FORCEIT, LET_NO_COMMAND
 {
     typval_T	*tv = tv_arg;
     typval_T	bool_tv;
@@ -3124,8 +3125,8 @@ set_var_const(
 	init_tv(tv);
     }
 
-    // ":const var = val" locks the value, but not in Vim9 script
-    if ((flags & LET_IS_CONST) && !vim9script)
+    // ":const var = val" locks the value; in Vim9 script only with ":const!"
+    if ((flags & LET_IS_CONST) && (!vim9script || (flags & LET_FORCEIT)))
 	// 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.