diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-11-06 18:27:17 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-11-06 18:27:17 +0000 |
commit | adbc08fd69433b5216e609a404d674f3e67eea9c (patch) | |
tree | 0b66f034862e8d7c40116326e64382fcafed0b7d | |
parent | 69a8bb8dc13571102537762b047747cc36b53d5d (diff) | |
download | vim-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.vim | 12 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9expr.c | 12 |
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 { |