diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index bc4a790273..5a178803e4 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 + 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 c454557cde..e7dc5a5b5c 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 840, /**/ 839, /**/ diff --git a/src/vim9expr.c b/src/vim9expr.c index 7a32974b69..7a089e9733 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 {