patch 8.2.3221: Vim9: argument types are not checked at compile time

Problem:    Vim9: argument types are not checked at compile time.
Solution:   Add several more type checks. (Yegappan Lakshmanan, closes #8632)
diff --git a/src/testdir/test_assert.vim b/src/testdir/test_assert.vim
index e0dc99e..51a0a3e 100644
--- a/src/testdir/test_assert.vim
+++ b/src/testdir/test_assert.vim
@@ -268,21 +268,21 @@
   catch
     let exp = v:exception
   endtry
-  call assert_match("E856: \"assert_fails()\" second argument", exp)
+  call assert_match("E1174: String required for argument 2", exp)
 
   try
     call assert_equal(1, assert_fails('xxx', 'E492', '', 'burp'))
   catch
     let exp = v:exception
   endtry
-  call assert_match("E1115: \"assert_fails()\" fourth argument must be a number", exp)
+  call assert_match("E1210: Number required for argument 4", exp)
 
   try
     call assert_equal(1, assert_fails('xxx', 'E492', '', 54, 123))
   catch
     let exp = v:exception
   endtry
-  call assert_match("E1116: \"assert_fails()\" fifth argument must be a string", exp)
+  call assert_match("E1174: String required for argument 5", exp)
 endfunc
 
 func Test_assert_fails_in_try_block()
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index e1316a0..4ca4737 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -234,6 +234,20 @@
   CheckDefFailure(['assert_exception("E1:", v:null)'], 'E1013: Argument 2: type mismatch, expected string but got special')
 enddef
 
+def Test_assert_fails()
+  CheckDefAndScriptFailure2(['assert_fails([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['assert_fails("a", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['assert_fails("a", "b", "c", "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
+  CheckDefAndScriptFailure2(['assert_fails("a", "b", "c", 4, 5)'], 'E1013: Argument 5: type mismatch, expected string but got number', 'E1174: String required for argument 5')
+enddef
+
+def Test_assert_inrange()
+  CheckDefAndScriptFailure2(['assert_inrange("a", 2, 3)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['assert_inrange(1, "b", 3)'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['assert_inrange(1, 2, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['assert_inrange(1, 2, 3, 4)'], 'E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4')
+enddef
+
 def Test_assert_match()
   CheckDefFailure(['assert_match({}, "b")'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>')
   CheckDefFailure(['assert_match("a", 1)'], 'E1013: Argument 2: type mismatch, expected string but got number')
@@ -1144,6 +1158,20 @@
   CheckDefAndScriptFailure2(['garbagecollect(20)'], 'E1013: Argument 1: type mismatch, expected bool but got number', 'E1023: Using a Number as a Bool')
 enddef
 
+def Test_get()
+  CheckDefAndScriptFailure2(['get("a", 1)'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E896: Argument of get() must be a List, Dictionary or Blob')
+  [3, 5, 2]->get(1)->assert_equal(5)
+  [3, 5, 2]->get(3)->assert_equal(0)
+  [3, 5, 2]->get(3, 9)->assert_equal(9)
+  assert_equal(get(0z102030, 2), 0x30)
+  {a: 7, b: 11, c: 13}->get('c')->assert_equal(13)
+  {10: 'a', 20: 'b', 30: 'd'}->get(20)->assert_equal('b')
+  function('max')->get('name')->assert_equal('max')
+  var F: func = function('min', [[5, 8, 6]])
+  F->get('name')->assert_equal('min')
+  F->get('args')->assert_equal([[5, 8, 6]])
+enddef
+
 def Test_getbufinfo()
   var bufinfo = getbufinfo(bufnr())
   getbufinfo('%')->assert_equal(bufinfo)
@@ -1703,6 +1731,15 @@
   var->assert_equal(['a', 'b'])
 enddef
 
+def Test_len()
+  CheckDefAndScriptFailure2(['len(true)'], 'E1013: Argument 1: type mismatch, expected list<any> but got bool', 'E701: Invalid type for len()')
+  assert_equal(2, "ab"->len())
+  assert_equal(3, 456->len())
+  assert_equal(0, []->len())
+  assert_equal(1, {a: 10}->len())
+  assert_equal(4, 0z20304050->len())
+enddef
+
 def Test_libcall()
   CheckFeature libcall
   CheckDefAndScriptFailure2(['libcall(1, "b", 3)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
@@ -1764,6 +1801,13 @@
   CheckDefAndScriptFailure2(['listener_remove("x")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1030: Using a String as a Number')
 enddef
 
+def Test_lua()
+  if !has('lua')
+    CheckFeature lua
+  endif
+  CheckDefAndScriptFailure2(['luaeval(10)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+enddef
+
 def Test_map()
   CheckDefAndScriptFailure2(['map("x", "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
   CheckDefAndScriptFailure2(['map(1, "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1')
@@ -2112,6 +2156,10 @@
   CheckDefAndScriptFailure2(['popup_clear(2)'], 'E1013: Argument 1: type mismatch, expected bool but got number', 'E1023: Using a Number as a Bool')
 enddef
 
+def Test_popup_close()
+  CheckDefAndScriptFailure2(['popup_close("a")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+enddef
+
 def Test_popup_create()
   # Pass variable of type 'any' to popup_create()
   var what: any = 'Hello'
@@ -2190,6 +2238,12 @@
   assert_equal(0, prevnonblank(1))
 enddef
 
+def Test_printf()
+  CheckDefAndScriptFailure2(['printf([1])'], 'E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1')
+  printf(0x10)->assert_equal('16')
+  assert_equal(" abc", "abc"->printf("%4s"))
+enddef
+
 def Test_prompt_getprompt()
   if !has('channel')
     CheckFeature channel
@@ -2798,6 +2852,10 @@
   CheckDefAndScriptFailure2(['setcursorcharpos(1, 2, "3")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
 enddef
 
+def Test_setenv()
+  CheckDefAndScriptFailure2(['setenv(1, 2)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+enddef
+
 def Test_setfperm()
   CheckDefFailure(['setfperm(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number')
   CheckDefFailure(['setfperm("a", 0z10)'], 'E1013: Argument 2: type mismatch, expected string but got blob')
@@ -2851,6 +2909,8 @@
   setreg('a', reginfo)
   getreginfo('a')->assert_equal(reginfo)
   assert_fails('setreg("ab", 0)', 'E1162:')
+  CheckDefAndScriptFailure2(['setreg(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['setreg("a", "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
 enddef 
 
 def Test_settabvar()
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 14684c0..c0ab29e 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -521,8 +521,8 @@
   assert_equal(344, n)
 
   try
-    echo len(v:true)
-  catch /E701:/
+    echo range(1, 2, 0)
+  catch /E726:/
     n = 355
   endtry
   assert_equal(355, n)