patch 8.2.1466: Vim9: cannot index or slice a variable with type "any"

Problem:    Vim9: cannot index or slice a variable with type "any".
Solution:   Add runtime index and slice.
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index 3ed36f3..4560da0 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -1091,6 +1091,50 @@
   call assert_equal(1, DictMember())
 enddef
 
+let somelist = [1, 2, 3, 4, 5]
+def AnyIndex(): number
+  let res = g:somelist[2]
+  return res
+enddef
+
+def Test_disassemble_any_index()
+  let instr = execute('disassemble AnyIndex')
+  assert_match('AnyIndex\_s*' ..
+        'let res = g:somelist\[2\]\_s*' ..
+        '\d LOADG g:somelist\_s*' ..
+        '\d PUSHNR 2\_s*' ..
+        '\d ANYINDEX\_s*' ..
+        '\d STORE $0\_s*' ..
+        'return res\_s*' ..
+        '\d LOAD $0\_s*' ..
+        '\d CHECKTYPE number stack\[-1\]\_s*' ..
+        '\d RETURN',
+        instr)
+  assert_equal(3, AnyIndex())
+enddef
+
+def AnySlice(): list<number>
+  let res = g:somelist[1:3]
+  return res
+enddef
+
+def Test_disassemble_any_slice()
+  let instr = execute('disassemble AnySlice')
+  assert_match('AnySlice\_s*' ..
+        'let res = g:somelist\[1:3\]\_s*' ..
+        '\d LOADG g:somelist\_s*' ..
+        '\d PUSHNR 1\_s*' ..
+        '\d PUSHNR 3\_s*' ..
+        '\d ANYSLICE\_s*' ..
+        '\d STORE $0\_s*' ..
+        'return res\_s*' ..
+        '\d LOAD $0\_s*' ..
+        '\d CHECKTYPE list stack\[-1\]\_s*' ..
+        '\d RETURN',
+        instr)
+  assert_equal([2, 3, 4], AnySlice())
+enddef
+
 def NegateNumber(): number
   let nr = 9
   let plus = +nr
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index 720f230..01ac3e6 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -1457,7 +1457,7 @@
 		4]
 
   call CheckDefFailure(["let x = 1234[3]"], 'E1107:')
-  call CheckDefExecFailure(["let x = g:anint[3]"], 'E1029:')
+  call CheckDefExecFailure(["let x = g:anint[3]"], 'E1062:')
 
   call CheckDefFailure(["let x = g:list_mixed[xxx]"], 'E1001:')
 
@@ -1768,9 +1768,91 @@
   call CheckDefExecFailure(["let d: dict<number>", "d = g:list_empty"], 'E1029: Expected dict but got list')
 enddef
 
-def Test_expr_index()
-  # getting the one member should clear the list only after getting the item
-  assert_equal('bbb', ['aaa', 'bbb', 'ccc'][1])
+def Test_expr7_any_index_slice()
+  let lines =<< trim END
+    # getting the one member should clear the list only after getting the item
+    assert_equal('bbb', ['aaa', 'bbb', 'ccc'][1])
+
+    # string is permissive, index out of range accepted
+    g:teststring = 'abcdef'
+    assert_equal('b', g:teststring[1])
+    assert_equal('', g:teststring[-1])
+    assert_equal('', g:teststring[99])
+
+    assert_equal('b', g:teststring[1:1])
+    assert_equal('bcdef', g:teststring[1:])
+    assert_equal('abcd', g:teststring[:3])
+    assert_equal('cdef', g:teststring[-4:])
+    assert_equal('abcdef', g:teststring[-9:])
+    assert_equal('abcd', g:teststring[:-3])
+    assert_equal('', g:teststring[:-9])
+
+    # blob index cannot be out of range
+    g:testblob = 0z01ab
+    assert_equal(0x01, g:testblob[0])
+    assert_equal(0xab, g:testblob[1])
+    assert_equal(0xab, g:testblob[-1])
+    assert_equal(0x01, g:testblob[-2])
+
+    # blob slice accepts out of range
+    assert_equal(0z01ab, g:testblob[0:1])
+    assert_equal(0z01, g:testblob[0:0])
+    assert_equal(0z01, g:testblob[-2:-2])
+    assert_equal(0zab, g:testblob[1:1])
+    assert_equal(0zab, g:testblob[-1:-1])
+    assert_equal(0z, g:testblob[2:2])
+    assert_equal(0z, g:testblob[0:-3])
+
+    # list index cannot be out of range
+    g:testlist = [0, 1, 2, 3]
+    assert_equal(0, g:testlist[0])
+    assert_equal(1, g:testlist[1])
+    assert_equal(3, g:testlist[3])
+    assert_equal(3, g:testlist[-1])
+    assert_equal(0, g:testlist[-4])
+    assert_equal(1, g:testlist[g:theone])
+
+    # list slice accepts out of range
+    assert_equal([0], g:testlist[0:0])
+    assert_equal([3], g:testlist[3:3])
+    assert_equal([0, 1], g:testlist[0:1])
+    assert_equal([0, 1, 2, 3], g:testlist[0:3])
+    assert_equal([0, 1, 2, 3], g:testlist[0:9])
+    assert_equal([], g:testlist[-1:1])
+    assert_equal([1], g:testlist[-3:1])
+    assert_equal([0, 1], g:testlist[-4:1])
+    assert_equal([0, 1], g:testlist[-9:1])
+    assert_equal([1, 2, 3], g:testlist[1:-1])
+    assert_equal([1], g:testlist[1:-3])
+    assert_equal([], g:testlist[1:-4])
+    assert_equal([], g:testlist[1:-9])
+
+    g:testdict = #{a: 1, b: 2}
+    assert_equal(1, g:testdict['a'])
+    assert_equal(2, g:testdict['b'])
+  END
+
+  CheckDefSuccess(lines)
+  CheckScriptSuccess(['vim9script'] + lines)
+
+  CheckDefExecFailure(['echo g:testblob[2]'], 'E979:')
+  CheckScriptFailure(['vim9script', 'echo g:testblob[2]'], 'E979:')
+  CheckDefExecFailure(['echo g:testblob[-3]'], 'E979:')
+  CheckScriptFailure(['vim9script', 'echo g:testblob[-3]'], 'E979:')
+
+  CheckDefExecFailure(['echo g:testlist[4]'], 'E684:')
+  CheckScriptFailure(['vim9script', 'echo g:testlist[4]'], 'E684:')
+  CheckDefExecFailure(['echo g:testlist[-5]'], 'E684:')
+  CheckScriptFailure(['vim9script', 'echo g:testlist[-5]'], 'E684:')
+
+  CheckDefExecFailure(['echo g:testdict["a":"b"]'], 'E719:')
+  CheckScriptFailure(['vim9script', 'echo g:testdict["a":"b"]'], 'E719:')
+  CheckDefExecFailure(['echo g:testdict[1]'], 'E716:')
+  CheckScriptFailure(['vim9script', 'echo g:testdict[1]'], 'E716:')
+
+  unlet g:teststring
+  unlet g:testblob
+  unlet g:testlist
 enddef
 
 def Test_expr_member_vim9script()
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 1e265be..3b8264f 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -793,8 +793,8 @@
   endtry
   assert_equal(99, n)
 
-  # TODO: this will change when index on "any" works
   try
+    # string slice returns a string, not a number
     n = g:astring[3]
   catch /E1029:/
     n = 77