changeset 23654:1974c5122506 v8.2.2369

patch 8.2.2369: Vim9: functions return true/false but can't be used as bool Commit: https://github.com/vim/vim/commit/3af15ab7888033fdfae0ae7085172aab794339a2 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 17 16:16:23 2021 +0100 patch 8.2.2369: Vim9: functions return true/false but can't be used as bool Problem: Vim9: functions return true/false but can't be used as bool. Solution: Add ret_number_bool(). (closes https://github.com/vim/vim/issues/7693)
author Bram Moolenaar <Bram@vim.org>
date Sun, 17 Jan 2021 16:30:05 +0100
parents f6bbb1105de2
children 1c9c8221f546
files src/evalfunc.c src/testdir/test_vim9_builtin.vim src/testdir/test_vim9_disassemble.vim src/version.c
diffstat 4 files changed, 97 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -449,6 +449,11 @@ ret_bool(int argcount UNUSED, type_T **a
     return &t_bool;
 }
     static type_T *
+ret_number_bool(int argcount UNUSED, type_T **argtypes UNUSED)
+{
+    return &t_number_bool;
+}
+    static type_T *
 ret_number(int argcount UNUSED, type_T **argtypes UNUSED)
 {
     return &t_number;
@@ -690,9 +695,9 @@ static funcentry_T global_functions[] =
     {"and",		2, 2, FEARG_1,	    NULL,
 			ret_number,	    f_and},
     {"append",		2, 2, FEARG_2,	    NULL,
-			ret_number,	    f_append},
+			ret_number_bool,    f_append},
     {"appendbufline",	3, 3, FEARG_3,	    NULL,
-			ret_number,	    f_appendbufline},
+			ret_number_bool,    f_appendbufline},
     {"argc",		0, 1, 0,	    NULL,
 			ret_number,	    f_argc},
     {"argidx",		0, 0, 0,	    NULL,
@@ -704,29 +709,29 @@ static funcentry_T global_functions[] =
     {"asin",		1, 1, FEARG_1,	    NULL,
 			ret_float,	    FLOAT_FUNC(f_asin)},
     {"assert_beeps",	1, 2, FEARG_1,	    NULL,
-			ret_number,	    f_assert_beeps},
+			ret_number_bool,    f_assert_beeps},
     {"assert_equal",	2, 3, FEARG_2,	    NULL,
-			ret_number,	    f_assert_equal},
+			ret_number_bool,    f_assert_equal},
     {"assert_equalfile", 2, 3, FEARG_1,	    NULL,
-			ret_number,	    f_assert_equalfile},
+			ret_number_bool,    f_assert_equalfile},
     {"assert_exception", 1, 2, 0,	    NULL,
-			ret_number,	    f_assert_exception},
+			ret_number_bool,    f_assert_exception},
     {"assert_fails",	1, 5, FEARG_1,	    NULL,
-			ret_number,	    f_assert_fails},
+			ret_number_bool,    f_assert_fails},
     {"assert_false",	1, 2, FEARG_1,	    NULL,
-			ret_number,	    f_assert_false},
+			ret_number_bool,    f_assert_false},
     {"assert_inrange",	3, 4, FEARG_3,	    NULL,
-			ret_number,	    f_assert_inrange},
+			ret_number_bool,    f_assert_inrange},
     {"assert_match",	2, 3, FEARG_2,	    NULL,
-			ret_number,	    f_assert_match},
+			ret_number_bool,    f_assert_match},
     {"assert_notequal",	2, 3, FEARG_2,	    NULL,
-			ret_number,	    f_assert_notequal},
+			ret_number_bool,    f_assert_notequal},
     {"assert_notmatch",	2, 3, FEARG_2,	    NULL,
-			ret_number,	    f_assert_notmatch},
+			ret_number_bool,    f_assert_notmatch},
     {"assert_report",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_assert_report},
+			ret_number_bool,    f_assert_report},
     {"assert_true",	1, 2, FEARG_1,	    NULL,
-			ret_number,	    f_assert_true},
+			ret_number_bool,    f_assert_true},
     {"atan",		1, 1, FEARG_1,	    NULL,
 			ret_float,	    FLOAT_FUNC(f_atan)},
     {"atan2",		2, 2, FEARG_1,	    NULL,
@@ -762,19 +767,19 @@ static funcentry_T global_functions[] =
     {"bufadd",		1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_bufadd},
     {"bufexists",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_bufexists},
+			ret_number_bool,    f_bufexists},
     {"buffer_exists",	1, 1, FEARG_1,	    NULL,	// obsolete
-			ret_number,	    f_bufexists},
+			ret_number_bool,    f_bufexists},
     {"buffer_name",	0, 1, FEARG_1,	    NULL,	// obsolete
 			ret_string,	    f_bufname},
     {"buffer_number",	0, 1, FEARG_1,	    NULL,	// obsolete
 			ret_number,	    f_bufnr},
     {"buflisted",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_buflisted},
+			ret_number_bool,    f_buflisted},
     {"bufload",		1, 1, FEARG_1,	    NULL,
 			ret_void,	    f_bufload},
     {"bufloaded",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_bufloaded},
+			ret_number_bool,    f_bufloaded},
     {"bufname",		0, 1, FEARG_1,	    NULL,
 			ret_string,	    f_bufname},
     {"bufnr",		0, 2, FEARG_1,	    NULL,
@@ -794,7 +799,7 @@ static funcentry_T global_functions[] =
     {"ceil",		1, 1, FEARG_1,	    NULL,
 			ret_float,	    FLOAT_FUNC(f_ceil)},
     {"ch_canread",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    JOB_FUNC(f_ch_canread)},
+			ret_number_bool,    JOB_FUNC(f_ch_canread)},
     {"ch_close",	1, 1, FEARG_1,	    NULL,
 			ret_void,	    JOB_FUNC(f_ch_close)},
     {"ch_close_in",	1, 1, FEARG_1,	    NULL,
@@ -852,7 +857,7 @@ static funcentry_T global_functions[] =
     {"complete_add",	1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_complete_add},
     {"complete_check",	0, 0, 0,	    NULL,
-			ret_number,	    f_complete_check},
+			ret_number_bool,    f_complete_check},
     {"complete_info",	0, 1, FEARG_1,	    NULL,
 			ret_dict_any,	    f_complete_info},
     {"confirm",		1, 4, FEARG_1,	    NULL,
@@ -880,19 +885,19 @@ static funcentry_T global_functions[] =
     {"deepcopy",	1, 2, FEARG_1,	    NULL,
 			ret_first_arg,	    f_deepcopy},
     {"delete",		1, 2, FEARG_1,	    NULL,
-			ret_number,	    f_delete},
+			ret_number_bool,    f_delete},
     {"deletebufline",	2, 3, FEARG_1,	    NULL,
-			ret_number,	    f_deletebufline},
+			ret_number_bool,    f_deletebufline},
     {"did_filetype",	0, 0, 0,	    NULL,
-			ret_number,	    f_did_filetype},
+			ret_number_bool,    f_did_filetype},
     {"diff_filler",	1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_diff_filler},
     {"diff_hlID",	2, 2, FEARG_1,	    NULL,
 			ret_number,	    f_diff_hlID},
     {"echoraw",		1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_echoraw},
+			ret_void,	    f_echoraw},
     {"empty",		1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_empty},
+			ret_number_bool,    f_empty},
     {"environ",		0, 0, 0,	    NULL,
 			ret_dict_string,    f_environ},
     {"escape",		2, 2, FEARG_1,	    NULL,
@@ -900,7 +905,7 @@ static funcentry_T global_functions[] =
     {"eval",		1, 1, FEARG_1,	    NULL,
 			ret_any,	    f_eval},
     {"eventhandler",	0, 0, 0,	    NULL,
-			ret_number,	    f_eventhandler},
+			ret_number_bool,    f_eventhandler},
     {"executable",	1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_executable},
     {"execute",		1, 2, FEARG_1,	    NULL,
@@ -908,7 +913,7 @@ static funcentry_T global_functions[] =
     {"exepath",		1, 1, FEARG_1,	    NULL,
 			ret_string,	    f_exepath},
     {"exists",		1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_exists},
+			ret_number_bool,    f_exists},
     {"exp",		1, 1, FEARG_1,	    NULL,
 			ret_float,	    FLOAT_FUNC(f_exp)},
     {"expand",		1, 3, FEARG_1,	    NULL,
@@ -922,9 +927,9 @@ static funcentry_T global_functions[] =
     {"feedkeys",	1, 2, FEARG_1,	    NULL,
 			ret_void,	    f_feedkeys},
     {"file_readable",	1, 1, FEARG_1,	    NULL,	// obsolete
-			ret_number,	    f_filereadable},
+			ret_number_bool,    f_filereadable},
     {"filereadable",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_filereadable},
+			ret_number_bool,    f_filereadable},
     {"filewritable",	1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_filewritable},
     {"filter",		2, 2, FEARG_1,	    NULL,
@@ -1010,7 +1015,7 @@ static funcentry_T global_functions[] =
     {"getftype",	1, 1, FEARG_1,	    NULL,
 			ret_string,	    f_getftype},
     {"getimstatus",	0, 0, 0,	    NULL,
-			ret_number,	    f_getimstatus},
+			ret_number_bool,    f_getimstatus},
     {"getjumplist",	0, 2, FEARG_1,	    NULL,
 			ret_list_any,	    f_getjumplist},
     {"getline",		1, 2, FEARG_1,	    NULL,
@@ -1062,21 +1067,21 @@ static funcentry_T global_functions[] =
     {"globpath",	2, 5, FEARG_2,	    NULL,
 			ret_any,	    f_globpath},
     {"has",		1, 2, 0,	    NULL,
-			ret_number,	    f_has},
+			ret_number_bool,    f_has},
     {"has_key",		2, 2, FEARG_1,	    NULL,
-			ret_number,	    f_has_key},
+			ret_number_bool,    f_has_key},
     {"haslocaldir",	0, 2, FEARG_1,	    NULL,
 			ret_number,	    f_haslocaldir},
     {"hasmapto",	1, 3, FEARG_1,	    NULL,
-			ret_number,	    f_hasmapto},
+			ret_number_bool,    f_hasmapto},
     {"highlightID",	1, 1, FEARG_1,	    NULL,	// obsolete
 			ret_number,	    f_hlID},
     {"highlight_exists",1, 1, FEARG_1,	    NULL,	// obsolete
-			ret_number,	    f_hlexists},
+			ret_number_bool,    f_hlexists},
     {"histadd",		2, 2, FEARG_2,	    NULL,
-			ret_number,	    f_histadd},
+			ret_number_bool,    f_histadd},
     {"histdel",		1, 2, FEARG_1,	    NULL,
-			ret_number,	    f_histdel},
+			ret_number_bool,    f_histdel},
     {"histget",		1, 2, FEARG_1,	    NULL,
 			ret_string,	    f_histget},
     {"histnr",		1, 1, FEARG_1,	    NULL,
@@ -1084,7 +1089,7 @@ static funcentry_T global_functions[] =
     {"hlID",		1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_hlID},
     {"hlexists",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_hlexists},
+			ret_number_bool,    f_hlexists},
     {"hostname",	0, 0, 0,	    NULL,
 			ret_string,	    f_hostname},
     {"iconv",		3, 3, FEARG_1,	    NULL,
@@ -1100,9 +1105,9 @@ static funcentry_T global_functions[] =
     {"inputlist",	1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_inputlist},
     {"inputrestore",	0, 0, 0,	    NULL,
-			ret_number,	    f_inputrestore},
+			ret_number_bool,    f_inputrestore},
     {"inputsave",	0, 0, 0,	    NULL,
-			ret_number,	    f_inputsave},
+			ret_number_bool,    f_inputsave},
     {"inputsecret",	1, 2, FEARG_1,	    NULL,
 			ret_string,	    f_inputsecret},
     {"insert",		2, 3, FEARG_1,	    arg3_insert,
@@ -1112,13 +1117,13 @@ static funcentry_T global_functions[] =
     {"invert",		1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_invert},
     {"isdirectory",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_isdirectory},
+			ret_number_bool,    f_isdirectory},
     {"isinf",		1, 1, FEARG_1,	    NULL,
 			ret_number,	    MATH_FUNC(f_isinf)},
     {"islocked",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_islocked},
+			ret_number_bool,    f_islocked},
     {"isnan",		1, 1, FEARG_1,	    NULL,
-			ret_number,	    MATH_FUNC(f_isnan)},
+			ret_number_bool,    MATH_FUNC(f_isnan)},
     {"items",		1, 1, FEARG_1,	    NULL,
 			ret_list_any,	    f_items},
     {"job_getchannel",	1, 1, FEARG_1,	    NULL,
@@ -1132,7 +1137,7 @@ static funcentry_T global_functions[] =
     {"job_status",	1, 1, FEARG_1,	    NULL,
 			ret_string,	    JOB_FUNC(f_job_status)},
     {"job_stop",	1, 2, FEARG_1,	    NULL,
-			ret_number,	    JOB_FUNC(f_job_stop)},
+			ret_number_bool,    JOB_FUNC(f_job_stop)},
     {"join",		1, 2, FEARG_1,	    NULL,
 			ret_string,	    f_join},
     {"js_decode",	1, 1, FEARG_1,	    NULL,
@@ -1166,7 +1171,7 @@ static funcentry_T global_functions[] =
     {"listener_flush",	0, 1, FEARG_1,	    NULL,
 			ret_void,	    f_listener_flush},
     {"listener_remove",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_listener_remove},
+			ret_number_bool,    f_listener_remove},
     {"localtime",	0, 0, 0,	    NULL,
 			ret_number,	    f_localtime},
     {"log",		1, 1, FEARG_1,	    NULL,
@@ -1200,7 +1205,7 @@ static funcentry_T global_functions[] =
     {"matcharg",	1, 1, FEARG_1,	    NULL,
 			ret_list_string,    f_matcharg},
     {"matchdelete",	1, 2, FEARG_1,	    NULL,
-			ret_number,	    f_matchdelete},
+			ret_number_bool,    f_matchdelete},
     {"matchend",	2, 4, FEARG_1,	    NULL,
 			ret_number,	    f_matchend},
     {"matchfuzzy",	2, 3, FEARG_1,	    NULL,
@@ -1226,7 +1231,7 @@ static funcentry_T global_functions[] =
     {"min",		1, 1, FEARG_1,	    NULL,
 			ret_any,	    f_min},
     {"mkdir",		1, 3, FEARG_1,	    NULL,
-			ret_number,	    f_mkdir},
+			ret_number_bool,    f_mkdir},
     {"mode",		0, 1, FEARG_1,	    NULL,
 			ret_string,	    f_mode},
     {"mzeval",		1, 1, FEARG_1,	    NULL,
@@ -1332,7 +1337,7 @@ static funcentry_T global_functions[] =
     {"pum_getpos",	0, 0, 0,	    NULL,
 			ret_dict_number,    f_pum_getpos},
     {"pumvisible",	0, 0, 0,	    NULL,
-			ret_number,	    f_pumvisible},
+			ret_number_bool,    f_pumvisible},
     {"py3eval",		1, 1, FEARG_1,	    NULL,
 			ret_any,
 #ifdef FEAT_PYTHON3
@@ -1396,7 +1401,7 @@ static funcentry_T global_functions[] =
     {"remove",		2, 3, FEARG_1,	    NULL,
 			ret_remove,	    f_remove},
     {"rename",		2, 2, FEARG_1,	    NULL,
-			ret_number,	    f_rename},
+			ret_number_bool,    f_rename},
     {"repeat",		2, 2, FEARG_1,	    NULL,
 			ret_first_arg,	    f_repeat},
     {"resolve",		1, 1, FEARG_1,	    NULL,
@@ -1432,7 +1437,7 @@ static funcentry_T global_functions[] =
     {"searchcount",	0, 1, FEARG_1,	    NULL,
 			ret_dict_any,	    f_searchcount},
     {"searchdecl",	1, 3, FEARG_1,	    NULL,
-			ret_number,	    f_searchdecl},
+			ret_number_bool,    f_searchdecl},
     {"searchpair",	3, 7, 0,	    NULL,
 			ret_number,	    f_searchpair},
     {"searchpairpos",	3, 7, 0,	    NULL,
@@ -1440,45 +1445,45 @@ static funcentry_T global_functions[] =
     {"searchpos",	1, 5, FEARG_1,	    NULL,
 			ret_list_number,    f_searchpos},
     {"server2client",	2, 2, FEARG_1,	    NULL,
-			ret_number,	    f_server2client},
+			ret_number_bool,    f_server2client},
     {"serverlist",	0, 0, 0,	    NULL,
 			ret_string,	    f_serverlist},
     {"setbufline",	3, 3, FEARG_3,	    NULL,
-			ret_number,	    f_setbufline},
+			ret_number_bool,    f_setbufline},
     {"setbufvar",	3, 3, FEARG_3,	    NULL,
 			ret_void,	    f_setbufvar},
     {"setcellwidths",	1, 1, FEARG_1,	    NULL,
 			ret_void,	    f_setcellwidths},
     {"setcharpos",	2, 2, FEARG_2,	    NULL,
-			ret_number,	    f_setcharpos},
+			ret_number_bool,    f_setcharpos},
     {"setcharsearch",	1, 1, FEARG_1,	    NULL,
 			ret_void,	    f_setcharsearch},
     {"setcmdpos",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_setcmdpos},
-    {"setcursorcharpos",	1, 3, FEARG_1,	    NULL,
-			ret_number,	    f_setcursorcharpos},
+			ret_number_bool,    f_setcmdpos},
+    {"setcursorcharpos", 1, 3, FEARG_1,	    NULL,
+			ret_number_bool,    f_setcursorcharpos},
     {"setenv",		2, 2, FEARG_2,	    NULL,
 			ret_void,	    f_setenv},
     {"setfperm",	2, 2, FEARG_1,	    NULL,
-			ret_number,	    f_setfperm},
+			ret_number_bool,    f_setfperm},
     {"setline",		2, 2, FEARG_2,	    NULL,
-			ret_number,	    f_setline},
+			ret_number_bool,    f_setline},
     {"setloclist",	2, 4, FEARG_2,	    NULL,
-			ret_number,	    f_setloclist},
+			ret_number_bool,    f_setloclist},
     {"setmatches",	1, 2, FEARG_1,	    NULL,
-			ret_number,	    f_setmatches},
+			ret_number_bool,    f_setmatches},
     {"setpos",		2, 2, FEARG_2,	    NULL,
-			ret_number,	    f_setpos},
+			ret_number_bool,    f_setpos},
     {"setqflist",	1, 3, FEARG_1,	    NULL,
-			ret_number,	    f_setqflist},
+			ret_number_bool,    f_setqflist},
     {"setreg",		2, 3, FEARG_2,	    NULL,
-			ret_number,	    f_setreg},
+			ret_number_bool,    f_setreg},
     {"settabvar",	3, 3, FEARG_3,	    NULL,
 			ret_void,	    f_settabvar},
     {"settabwinvar",	4, 4, FEARG_4,	    NULL,
 			ret_void,	    f_settabwinvar},
     {"settagstack",	2, 3, FEARG_2,	    NULL,
-			ret_number,	    f_settagstack},
+			ret_number_bool,    f_settagstack},
     {"setwinvar",	3, 3, FEARG_3,	    NULL,
 			ret_void,	    f_setwinvar},
     {"sha256",		1, 1, FEARG_1,	    NULL,
@@ -1506,9 +1511,9 @@ static funcentry_T global_functions[] =
     {"sign_placelist",	1, 1, FEARG_1,	    NULL,
 			ret_list_number,    SIGN_FUNC(f_sign_placelist)},
     {"sign_undefine",	0, 1, FEARG_1,	    NULL,
-			ret_number,	    SIGN_FUNC(f_sign_undefine)},
+			ret_number_bool,    SIGN_FUNC(f_sign_undefine)},
     {"sign_unplace",	1, 2, FEARG_1,	    NULL,
-			ret_number,	    SIGN_FUNC(f_sign_unplace)},
+			ret_number_bool,    SIGN_FUNC(f_sign_unplace)},
     {"sign_unplacelist", 1, 2, FEARG_1,	    NULL,
 			ret_list_number,    SIGN_FUNC(f_sign_unplacelist)},
     {"simplify",	1, 1, FEARG_1,	    NULL,
@@ -1788,7 +1793,7 @@ static funcentry_T global_functions[] =
     {"win_gettype",	0, 1, FEARG_1,	    NULL,
 			ret_string,	    f_win_gettype},
     {"win_gotoid",	1, 1, FEARG_1,	    NULL,
-			ret_number,	    f_win_gotoid},
+			ret_number_bool,    f_win_gotoid},
     {"win_id2tabwin",	1, 1, FEARG_1,	    NULL,
 			ret_list_number,    f_win_id2tabwin},
     {"win_id2win",	1, 1, FEARG_1,	    NULL,
@@ -1796,7 +1801,7 @@ static funcentry_T global_functions[] =
     {"win_screenpos",	1, 1, FEARG_1,	    NULL,
 			ret_list_number,    f_win_screenpos},
     {"win_splitmove",   2, 3, FEARG_1,	    NULL,
-			ret_number,	    f_win_splitmove},
+			ret_number_bool,    f_win_splitmove},
     {"winbufnr",	1, 1, FEARG_1,	    NULL,
 			ret_number,	    f_winbufnr},
     {"wincol",		0, 0, 0,	    NULL,
@@ -1822,7 +1827,7 @@ static funcentry_T global_functions[] =
     {"wordcount",	0, 0, 0,	    NULL,
 			ret_dict_number,    f_wordcount},
     {"writefile",	2, 3, FEARG_1,	    NULL,
-			ret_number,	    f_writefile},
+			ret_number_bool,    f_writefile},
     {"xor",		2, 2, FEARG_1,	    NULL,
 			ret_number,	    f_xor},
 };
@@ -8310,7 +8315,7 @@ f_setcharsearch(typval_T *argvars, typva
  * "setcursorcharpos" function
  */
     static void
-f_setcursorcharpos(typval_T *argvars, typval_T *rettv UNUSED)
+f_setcursorcharpos(typval_T *argvars, typval_T *rettv)
 {
     set_cursorpos(argvars, rettv, TRUE);
 }
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -115,6 +115,21 @@ def Test_add_blob()
   CheckDefExecFailure(lines, 'E1131:', 2)
 enddef
 
+def Test_append()
+  new
+  setline(1, range(3))
+  var res1: number = append(1, 'one')
+  assert_equal(0, res1)
+  var res2: bool = append(3, 'two')
+  assert_equal(false, res2)
+  assert_equal(['0', 'one', '1', 'two', '2'], getline(1, 6))
+enddef
+
+def Test_buflisted()
+  var res: bool = buflisted('asdf')
+  assert_equal(false, res)
+enddef
+
 def Test_bufname()
   split SomeFile
   bufname('%')->assert_equal('SomeFile')
@@ -199,6 +214,11 @@ def Test_cursor()
   CheckDefExecAndScriptFailure(lines, 'E475:')
 enddef
 
+def Test_delete()
+  var res: bool = delete('doesnotexist')
+  assert_equal(true, res)
+enddef
+
 def Test_executable()
   assert_false(executable(""))
   assert_false(executable(test_null_string()))
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -762,7 +762,7 @@ def Test_disassemble_const_expr()
             'if has("gui_running")\_s*' ..
             '\d PUSHS "gui_running"\_s*' ..
             '\d BCALL has(argc 1)\_s*' ..
-            '\d COND2BOOL\_s*' ..
+            '\d 2BOOL (!!val)\_s*' ..
             '\d JUMP_IF_FALSE -> \d\_s*' ..
             '  echo "yes"\_s*' ..
             '\d PUSHS "yes"\_s*' ..
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2369,
+/**/
     2368,
 /**/
     2367,