changeset 31010:4b9b76aac30c v9.0.0840

patch 9.0.0840: cannot change a slice of a const list Commit: https://github.com/vim/vim/commit/adbc08fd69433b5216e609a404d674f3e67eea9c Author: Bram Moolenaar <Bram@vim.org> Date: Sun Nov 6 18:27:17 2022 +0000 patch 9.0.0840: cannot change a slice of a const list Problem: Cannot change a slice of a const list. (Takumi KAGIYAMA) Solution: Remove the const flag from the slice type. (closes https://github.com/vim/vim/issues/11490)
author Bram Moolenaar <Bram@vim.org>
date Sun, 06 Nov 2022 19:30:08 +0100
parents 5bbf18bfeb96
children 768705736aab
files src/testdir/test_vim9_expr.vim src/version.c src/vim9expr.c
diffstat 3 files changed, 26 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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,
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -185,6 +185,18 @@ compile_member(int is_slice, int *keepin
 	    // 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
 	{