patch 8.2.4302: Vim9: return type of getline() is too strict

Problem:    Vim9: return type of getline() is too strict.
Solution:   Make the declared type list<any>.  Also do this for other
            functions returning a list of a specific type.
diff --git a/src/evalfunc.c b/src/evalfunc.c
index a584443..e1dca94 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1050,46 +1050,42 @@
     static type_T *
 ret_list_number(int argcount UNUSED,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
-{
-    return &t_list_number;
-}
-    static type_T *
-ret_range(int argcount UNUSED,
-	type2_T *argtypes UNUSED,
 	type_T	**decl_type)
 {
-    // returning a list<number>, but it's not declared as such
     *decl_type = &t_list_any;
     return &t_list_number;
 }
     static type_T *
 ret_list_string(int argcount UNUSED,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
+    *decl_type = &t_list_any;
     return &t_list_string;
 }
     static type_T *
 ret_list_dict_any(int argcount UNUSED,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
+    *decl_type = &t_list_any;
     return &t_list_dict_any;
 }
     static type_T *
 ret_list_items(int argcount UNUSED,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
+    *decl_type = &t_list_any;
     return &t_list_list_any;
 }
 
     static type_T *
 ret_list_string_items(int argcount UNUSED,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
+    *decl_type = &t_list_any;
     return &t_list_list_string;
 }
     static type_T *
@@ -1102,10 +1098,13 @@
     static type_T *
 ret_job_info(int argcount,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
     if (argcount == 0)
+    {
+	*decl_type = &t_list_any;
 	return &t_list_job;
+    }
     return &t_dict_any;
 }
     static type_T *
@@ -1252,7 +1251,10 @@
 	type2_T *argtypes UNUSED,
 	type_T	**decl_type UNUSED)
 {
-    return argcount == 1 ? &t_string : &t_list_string;
+    if (argcount == 1)
+	return &t_string;
+    *decl_type = &t_list_any;
+    return &t_list_string;
 }
 // for finddir()
     static type_T *
@@ -1273,10 +1275,11 @@
     static type_T *
 ret_list_or_dict_0(int argcount,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
     if (argcount > 0)
 	return &t_dict_any;
+    *decl_type = &t_list_any;
     return &t_list_dict_any;
 }
 
@@ -1287,21 +1290,25 @@
     static type_T *
 ret_list_or_dict_1(int argcount,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
     if (argcount > 1)
 	return &t_dict_any;
+    *decl_type = &t_list_any;
     return &t_list_dict_any;
 }
 
     static type_T *
 ret_argv(int argcount,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
     // argv() returns list of strings
     if (argcount == 0)
+    {
+	*decl_type = &t_list_any;
 	return &t_list_string;
+    }
 
     // argv(0) returns a string, but argv(-1] returns a list
     return &t_any;
@@ -1331,11 +1338,14 @@
     static type_T *
 ret_getreg(int argcount,
 	type2_T *argtypes UNUSED,
-	type_T	**decl_type UNUSED)
+	type_T	**decl_type)
 {
     // Assume that if the third argument is passed it's non-zero
     if (argcount == 3)
+    {
+	*decl_type = &t_list_any;
 	return &t_list_string;
+    }
     return &t_string;
 }
 
@@ -1749,7 +1759,7 @@
 			ret_list_string,    f_getcompletion},
     {"getcurpos",	0, 1, FEARG_1,	    arg1_number,
 			ret_list_number,    f_getcurpos},
-    {"getcursorcharpos",	0, 1, FEARG_1,	    arg1_number,
+    {"getcursorcharpos", 0, 1, FEARG_1,	    arg1_number,
 			ret_list_number,    f_getcursorcharpos},
     {"getcwd",		0, 2, FEARG_1,	    arg2_number,
 			ret_string,	    f_getcwd},
@@ -2124,7 +2134,7 @@
     {"rand",		0, 1, FEARG_1,	    arg1_list_number,
 			ret_number,	    f_rand},
     {"range",		1, 3, FEARG_1,	    arg3_number,
-			ret_range,	    f_range},
+			ret_list_number,    f_range},
     {"readblob",	1, 1, FEARG_1,	    arg1_string,
 			ret_blob,	    f_readblob},
     {"readdir",		1, 3, FEARG_1,	    arg3_string_any_dict,
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 6e53d27..743cb50 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -313,6 +313,7 @@
 enddef
 
 def Test_blob2list()
+  assert_equal(['x', 'x'], blob2list(0z1234)->map((_, _) => 'x'))
   v9.CheckDefAndScriptFailure(['blob2list(10)'], ['E1013: Argument 1: type mismatch, expected blob but got number', 'E1238: Blob required for argument 1'])
 enddef
 
@@ -1529,6 +1530,8 @@
   getbufline(-1, '$', '$')->assert_equal([])
   getbufline(-1, 1, '$')->assert_equal([])
 
+  assert_equal([7, 7, 7], getbufline('#', 1, '$')->map((_, _) => 7))
+
   assert_fails('getbufline("", "$a", "$b")', ['E1030: Using a String as a Number: "$a"', 'E1030: Using a String as a Number: "$a"'])
   assert_fails('getbufline("", "$", "$b")', ['E1030: Using a String as a Number: "$b"', 'E1030: Using a String as a Number: "$b"'])
   bwipe!
@@ -1561,6 +1564,8 @@
 enddef
 
 def Test_getcharpos()
+  assert_equal(['x', 'x', 'x', 'x'], getcharpos('.')->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['getcharpos(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
   v9.CheckDefAndScriptFailure(['getcharpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
   v9.CheckDefExecAndScriptFailure(['getcharpos("")'], 'E1209: Invalid value for a line number')
@@ -1584,10 +1589,14 @@
 enddef
 
 def Test_getcurpos()
+  assert_equal(['x', 'x', 'x', 'x', 'x'], getcurpos()->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['getcurpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
 enddef
 
 def Test_getcursorcharpos()
+  assert_equal(['x', 'x', 'x', 'x', 'x'], getcursorcharpos()->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['getcursorcharpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
 enddef
 
@@ -1664,6 +1673,8 @@
       normal 2Gvjv
       assert_equal('there', getline("'<"))
       assert_equal('again', getline("'>"))
+
+      assert_equal([3, 3, 3], getline(1, 3)->map((_, _) => 3))
   END
   v9.CheckDefAndScriptSuccess(lines)
 
@@ -1700,6 +1711,8 @@
 enddef
 
 def Test_getpos()
+  assert_equal(['x', 'x', 'x', 'x'], getpos('.')->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['getpos(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
   assert_equal([0, 1, 1, 0], getpos('.'))
   v9.CheckDefExecFailure(['getpos("a")'], 'E1209:')
@@ -1723,6 +1736,8 @@
   var lines = ['aaa', 'bbb', 'ccc']
   setreg('a', lines)
   getreg('a', true, true)->assert_equal(lines)
+  assert_equal([7, 7, 7], getreg('a', true, true)->map((_, _) => 7))
+
   assert_fails('getreg("ab")', 'E1162:')
   v9.CheckDefAndScriptFailure(['getreg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
   v9.CheckDefAndScriptFailure(['getreg(".", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
@@ -1786,6 +1801,8 @@
 enddef
 
 def Test_getwinpos()
+  assert_equal(['x', 'x'], getwinpos()->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['getwinpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
 enddef
 
@@ -2020,6 +2037,7 @@
   v9.CheckDefFailure(['[]->items()'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
   assert_equal([['a', 10], ['b', 20]], {'a': 10, 'b': 20}->items())
   assert_equal([], {}->items())
+  assert_equal(['x', 'x'], {'a': 10, 'b': 20}->items()->map((_, _) => 'x'))
 enddef
 
 def Test_job_getchannel()
@@ -2089,6 +2107,8 @@
 enddef
 
 def Test_keys()
+  assert_equal([7, 7], keys({a: 1, b: 2})->map((_, _) => 7))
+
   v9.CheckDefAndScriptFailure(['keys([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 1'])
   assert_equal(['a'], {a: 'v'}->keys())
   assert_equal([], {}->keys())
@@ -2881,6 +2901,7 @@
   writefile(text, 'Xreadfile')
   var read: list<string> = readfile('Xreadfile')
   assert_equal(text, read)
+  assert_equal([7, 7, 7], readfile('Xreadfile')->map((_, _) => 7))
 
   var lines =<< trim END
       var read: dict<string> = readfile('Xreadfile')
@@ -3089,6 +3110,8 @@
 enddef
 
 def Test_screenchars()
+  assert_equal(['x'], screenchars(1, 1)->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['screenchars("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
   v9.CheckDefAndScriptFailure(['screenchars(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
 enddef
@@ -3189,6 +3212,8 @@
   assert_equal(0, searchpair('', '', ''))
   assert_equal([0, 0], searchpairpos('', '', ''))
 
+  assert_equal(['x', 'x'], searchpairpos('', '', '')->map((_, _) => 'x'))
+
   var lines =<< trim END
       vim9script
       setline(1, '()')
@@ -3247,6 +3272,8 @@
 enddef
 
 def Test_searchpos()
+  assert_equal(['x', 'x'], searchpos('.')->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['searchpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
   v9.CheckDefAndScriptFailure(['searchpos("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
   v9.CheckDefAndScriptFailure(['searchpos("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
@@ -3685,6 +3712,9 @@
 enddef
 
 def Test_srand()
+  var expected = srand()->len()->range()->map((_, _) => 'x')
+  assert_equal(expected, srand()->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['srand("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
   type(srand(100))->assert_equal(v:t_list)
 enddef
@@ -3707,6 +3737,8 @@
 enddef
 
 def Test_str2list()
+  assert_equal(['x', 'x', 'x'], str2list('abc')->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['str2list(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
   v9.CheckDefAndScriptFailure(['str2list("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
   assert_equal([97], str2list('a'))
@@ -3914,6 +3946,7 @@
   v9.CheckDefAndScriptFailure(['tabpagebuflist("t")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
   assert_equal([bufnr('')], tabpagebuflist())
   assert_equal([bufnr('')], tabpagebuflist(1))
+  assert_equal(['x'], tabpagebuflist()->map((_, _) => 'x'))
 enddef
 
 def Test_tabpagenr()
@@ -4293,6 +4326,8 @@
 enddef
 
 def Test_win_screenpos()
+  assert_equal(['x', 'x'], win_screenpos(1)->map((_, _) => 'x'))
+
   v9.CheckDefAndScriptFailure(['win_screenpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
 enddef
 
diff --git a/src/version.c b/src/version.c
index 84ab409..89a22a0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4302,
+/**/
     4301,
 /**/
     4300,