To: vim_dev@googlegroups.com Subject: Patch 8.2.4302 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4302 Problem: Vim9: return type of getline() is too strict. Solution: Make the declared type list. Also do this for other functions returning a list of a specific type. Files: src/evalfunc.c, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.4301/src/evalfunc.c 2022-02-04 10:45:34.944240854 +0000 --- src/evalfunc.c 2022-02-05 18:10:57.056688820 +0000 *************** *** 1050,1095 **** 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, 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) { return &t_list_string; } static type_T * ret_list_dict_any(int argcount UNUSED, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { return &t_list_dict_any; } static type_T * ret_list_items(int argcount UNUSED, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { return &t_list_list_any; } static type_T * ret_list_string_items(int argcount UNUSED, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { return &t_list_list_string; } static type_T * --- 1050,1091 ---- static type_T * ret_list_number(int argcount UNUSED, type2_T *argtypes UNUSED, type_T **decl_type) { *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) { + *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) { + *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) { + *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) { + *decl_type = &t_list_any; return &t_list_list_string; } static type_T * *************** *** 1102,1111 **** static type_T * ret_job_info(int argcount, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { if (argcount == 0) return &t_list_job; return &t_dict_any; } static type_T * --- 1098,1110 ---- static type_T * ret_job_info(int argcount, type2_T *argtypes 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,1258 **** type2_T *argtypes UNUSED, type_T **decl_type UNUSED) { ! return argcount == 1 ? &t_string : &t_list_string; } // for finddir() static type_T * --- 1251,1260 ---- type2_T *argtypes UNUSED, type_T **decl_type UNUSED) { ! if (argcount == 1) ! return &t_string; ! *decl_type = &t_list_any; ! return &t_list_string; } // for finddir() static type_T * *************** *** 1273,1282 **** static type_T * ret_list_or_dict_0(int argcount, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { if (argcount > 0) return &t_dict_any; return &t_list_dict_any; } --- 1275,1285 ---- static type_T * ret_list_or_dict_0(int argcount, type2_T *argtypes UNUSED, ! type_T **decl_type) { if (argcount > 0) return &t_dict_any; + *decl_type = &t_list_any; return &t_list_dict_any; } *************** *** 1287,1307 **** static type_T * ret_list_or_dict_1(int argcount, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { if (argcount > 1) return &t_dict_any; return &t_list_dict_any; } static type_T * ret_argv(int argcount, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { // argv() returns list of strings if (argcount == 0) return &t_list_string; // argv(0) returns a string, but argv(-1] returns a list return &t_any; --- 1290,1314 ---- static type_T * ret_list_or_dict_1(int argcount, type2_T *argtypes 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) { // 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,1341 **** static type_T * ret_getreg(int argcount, type2_T *argtypes UNUSED, ! type_T **decl_type UNUSED) { // Assume that if the third argument is passed it's non-zero if (argcount == 3) return &t_list_string; return &t_string; } --- 1338,1351 ---- static type_T * ret_getreg(int argcount, type2_T *argtypes 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,1755 **** ret_list_string, f_getcompletion}, {"getcurpos", 0, 1, FEARG_1, arg1_number, ret_list_number, f_getcurpos}, ! {"getcursorcharpos", 0, 1, FEARG_1, arg1_number, ret_list_number, f_getcursorcharpos}, {"getcwd", 0, 2, FEARG_1, arg2_number, ret_string, f_getcwd}, --- 1759,1765 ---- ret_list_string, f_getcompletion}, {"getcurpos", 0, 1, FEARG_1, arg1_number, ret_list_number, f_getcurpos}, ! {"getcursorcharpos", 0, 1, FEARG_1, arg1_number, ret_list_number, f_getcursorcharpos}, {"getcwd", 0, 2, FEARG_1, arg2_number, ret_string, f_getcwd}, *************** *** 2124,2130 **** {"rand", 0, 1, FEARG_1, arg1_list_number, ret_number, f_rand}, {"range", 1, 3, FEARG_1, arg3_number, ! ret_range, f_range}, {"readblob", 1, 1, FEARG_1, arg1_string, ret_blob, f_readblob}, {"readdir", 1, 3, FEARG_1, arg3_string_any_dict, --- 2134,2140 ---- {"rand", 0, 1, FEARG_1, arg1_list_number, ret_number, f_rand}, {"range", 1, 3, FEARG_1, arg3_number, ! 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, *** ../vim-8.2.4301/src/testdir/test_vim9_builtin.vim 2022-02-05 14:05:48.128149067 +0000 --- src/testdir/test_vim9_builtin.vim 2022-02-05 17:54:06.266508656 +0000 *************** *** 313,318 **** --- 313,319 ---- 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,1534 **** --- 1530,1537 ---- 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,1566 **** --- 1564,1571 ---- 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,1593 **** --- 1589,1602 ---- 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,1669 **** --- 1673,1680 ---- 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,1705 **** --- 1711,1718 ---- 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,1728 **** --- 1736,1743 ---- 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,1791 **** --- 1801,1808 ---- 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,2025 **** --- 2037,2043 ---- v9.CheckDefFailure(['[]->items()'], 'E1013: Argument 1: type mismatch, expected dict but got list') 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,2094 **** --- 2107,2114 ---- 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 but got list', 'E1206: Dictionary required for argument 1']) assert_equal(['a'], {a: 'v'}->keys()) assert_equal([], {}->keys()) *************** *** 2881,2886 **** --- 2901,2907 ---- writefile(text, 'Xreadfile') var read: list = readfile('Xreadfile') assert_equal(text, read) + assert_equal([7, 7, 7], readfile('Xreadfile')->map((_, _) => 7)) var lines =<< trim END var read: dict = readfile('Xreadfile') *************** *** 3089,3094 **** --- 3110,3117 ---- 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,3194 **** --- 3212,3219 ---- assert_equal(0, searchpair('', '', '')) assert_equal([0, 0], searchpairpos('', '', '')) + assert_equal(['x', 'x'], searchpairpos('', '', '')->map((_, _) => 'x')) + var lines =<< trim END vim9script setline(1, '()') *************** *** 3247,3252 **** --- 3272,3279 ---- 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,3690 **** --- 3712,3720 ---- 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,3712 **** --- 3737,3744 ---- 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,3919 **** --- 3946,3952 ---- 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,4298 **** --- 4326,4333 ---- 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 *** ../vim-8.2.4301/src/version.c 2022-02-05 14:05:48.132149062 +0000 --- src/version.c 2022-02-05 17:15:39.650727891 +0000 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 4302, /**/ -- hundred-and-one symptoms of being an internet addict: 2. You kiss your girlfriend's home page. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///