To: vim_dev@googlegroups.com Subject: Patch 8.2.3857 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3857 Problem: Vim9: inconsistent error for using function(). Solution: Use a runtime type check for the result of function(). (closes #8492) Files: src/evalfunc.c, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.3856/src/evalfunc.c 2021-12-18 18:33:41.095346414 +0000 --- src/evalfunc.c 2021-12-20 09:06:50.037268198 +0000 *************** *** 957,962 **** --- 957,967 ---- return &t_func_any; } static type_T * + ret_func_unknown(int argcount UNUSED, type_T **argtypes UNUSED) + { + return &t_func_unknown; + } + static type_T * ret_channel(int argcount UNUSED, type_T **argtypes UNUSED) { return &t_channel; *************** *** 1065,1072 **** return &t_string; } - static type_T *ret_f_function(int argcount, type_T **argtypes); - /* * Array with names and number of arguments of all internal functions * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! --- 1070,1075 ---- *************** *** 1429,1437 **** {"fullcommand", 1, 1, FEARG_1, arg1_string, ret_string, f_fullcommand}, {"funcref", 1, 3, FEARG_1, arg3_any_list_dict, ! ret_func_any, f_funcref}, {"function", 1, 3, FEARG_1, arg3_any_list_dict, ! ret_f_function, f_function}, {"garbagecollect", 0, 1, 0, arg1_bool, ret_void, f_garbagecollect}, {"get", 2, 3, FEARG_1, arg23_get, --- 1432,1440 ---- {"fullcommand", 1, 1, FEARG_1, arg1_string, ret_string, f_fullcommand}, {"funcref", 1, 3, FEARG_1, arg3_any_list_dict, ! ret_func_unknown, f_funcref}, {"function", 1, 3, FEARG_1, arg3_any_list_dict, ! ret_func_unknown, f_function}, {"garbagecollect", 0, 1, 0, arg1_bool, ret_void, f_garbagecollect}, {"get", 2, 3, FEARG_1, arg23_get, *************** *** 4170,4184 **** common_function(argvars, rettv, TRUE); } - static type_T * - ret_f_function(int argcount, type_T **argtypes) - { - if (argcount == 1 && argtypes[0]->tt_type == VAR_STRING) - return &t_func_any; - // Need to check the type at runtime, the function may be defined later. - return &t_func_unknown; - } - /* * "function()" function */ --- 4173,4178 ---- *** ../vim-8.2.3856/src/testdir/test_vim9_builtin.vim 2021-12-19 18:33:17.321954811 +0000 --- src/testdir/test_vim9_builtin.vim 2021-12-20 09:31:36.725858433 +0000 *************** *** 1258,1264 **** enddef def Test_foldclosed() ! CheckDefAndScriptFailure(['foldclosed(function("min"))'], ['E1013: Argument 1: type mismatch, expected string but got func(...): any', 'E1220: String or Number required for argument 1']) CheckDefExecAndScriptFailure(['foldclosed("")'], 'E1209: Invalid value for a line number') assert_equal(-1, foldclosed(1)) assert_equal(-1, foldclosed('$')) --- 1258,1264 ---- enddef def Test_foldclosed() ! CheckDefAndScriptFailure(['foldclosed(function("min"))'], ['E1013: Argument 1: type mismatch, expected string but got func(...): unknown', 'E1220: String or Number required for argument 1']) CheckDefExecAndScriptFailure(['foldclosed("")'], 'E1209: Invalid value for a line number') assert_equal(-1, foldclosed(1)) assert_equal(-1, foldclosed('$')) *************** *** 1312,1322 **** --- 1312,1380 ---- def Test_funcref() CheckDefAndScriptFailure(['funcref("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list but got number', 'E1211: List required for argument 2']) CheckDefAndScriptFailure(['funcref("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict but got list', 'E1206: Dictionary required for argument 3']) + + var lines =<< trim END + vim9script + def UseBool(b: bool) + enddef + def GetRefOk() + var Ref1: func(bool) = funcref(UseBool) + var Ref2: func(bool) = funcref('UseBool') + enddef + def GetRefBad() + # only fails at runtime + var Ref1: func(number) = funcref(UseBool) + enddef + defcompile + GetRefOk() + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + def UseBool(b: bool) + enddef + def GetRefBad() + # only fails at runtime + var Ref1: func(number) = funcref(UseBool) + enddef + GetRefBad() + END + CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)') enddef def Test_function() CheckDefAndScriptFailure(['function("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list but got number', 'E1211: List required for argument 2']) CheckDefAndScriptFailure(['function("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict but got list', 'E1206: Dictionary required for argument 3']) + + var lines =<< trim END + vim9script + def UseBool(b: bool) + enddef + def GetRefOk() + var Ref1: func(bool) = function(UseBool) + var Ref2: func(bool) = function('UseBool') + enddef + def GetRefBad() + # only fails at runtime + var Ref1: func(number) = function(UseBool) + enddef + defcompile + GetRefOk() + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + def UseBool(b: bool) + enddef + def GetRefBad() + # only fails at runtime + var Ref1: func(number) = function(UseBool) + enddef + GetRefBad() + END + CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)') enddef def Test_garbagecollect() *** ../vim-8.2.3856/src/version.c 2021-12-19 21:34:01.699292755 +0000 --- src/version.c 2021-12-20 09:35:10.885627066 +0000 *************** *** 751,752 **** --- 751,754 ---- { /* Add new patch number below this line */ + /**/ + 3857, /**/ -- hundred-and-one symptoms of being an internet addict: 85. Choice between paying Compuserve bill and paying for kids education is a no brainer -- although a bit painful for your kids. /// 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 ///