summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-11-06 18:27:17 +0000
committerBram Moolenaar <Bram@vim.org>2022-11-06 18:27:17 +0000
commitadbc08fd69433b5216e609a404d674f3e67eea9c (patch)
tree0b66f034862e8d7c40116326e64382fcafed0b7d
parent69a8bb8dc13571102537762b047747cc36b53d5d (diff)
downloadvim-git-9.0.0840.tar.gz
patch 9.0.0840: cannot change a slice of a const listv9.0.0840
Problem: Cannot change a slice of a const list. (Takumi KAGIYAMA) Solution: Remove the const flag from the slice type. (closes #11490)
-rw-r--r--src/testdir/test_vim9_expr.vim12
-rw-r--r--src/version.c2
-rw-r--r--src/vim9expr.c12
3 files changed, 26 insertions, 0 deletions
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index bc4a79027..5a178803e 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -3132,6 +3132,18 @@ def Test_expr9_any_index_slice()
unlet g:testlist
enddef
+def s:GetList(): list<string>
+ return ['a', 'b', 'z']
+enddef
+
+def Test_slice_const_list()
+ const list = GetList()
+ final sliced = list[0 : 1]
+ # OK to change the list after slicing, it is a copy now
+ add(sliced, 'Z')
+ assert_equal(['a', 'b', 'Z'], sliced)
+enddef
+
def Test_expr9_const_any_index_slice()
var lines =<< trim END
vim9script
diff --git a/src/version.c b/src/version.c
index c454557cd..e7dc5a5b5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 840,
+/**/
839,
/**/
838,
diff --git a/src/vim9expr.c b/src/vim9expr.c
index 7a32974b6..7a089e973 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -185,6 +185,18 @@ compile_member(int is_slice, int *keeping_dict, cctx_T *cctx)
// a copy is made so the member type is no longer declared
if (typep->type_decl->tt_type == VAR_LIST)
typep->type_decl = &t_list_any;
+
+ // a copy is made, the composite is no longer "const"
+ if (typep->type_curr->tt_flags & TTFLAG_CONST)
+ {
+ type_T *type = copy_type(typep->type_curr, cctx->ctx_type_list);
+
+ if (type != typep->type_curr) // did get a copy
+ {
+ type->tt_flags &= ~(TTFLAG_CONST | TTFLAG_STATIC);
+ typep->type_curr = type;
+ }
+ }
}
else
{