# HG changeset patch # User Bram Moolenaar # Date 1662031805 -7200 # Node ID adb0de8be4ce9dc765f984c23512af5417bcffdd # Parent 3fb163e2ef6ccfdfe6f553a4750458b7b43956fa patch 9.0.0345: error message for list argument could be clearer Commit: https://github.com/vim/vim/commit/d83392a43a48c566c0f3b76382a3648584dae32b Author: Bram Moolenaar Date: Thu Sep 1 12:22:46 2022 +0100 patch 9.0.0345: error message for list argument could be clearer Problem: Error message for list argument could be clearer. Solution: Include the argument number. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/11027) diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt --- a/runtime/doc/vim9.txt +++ b/runtime/doc/vim9.txt @@ -1618,7 +1618,7 @@ type, it can not be used in Vim9 script. *E1211* *E1217* *E1218* *E1219* *E1220* *E1221* *E1222* *E1223* *E1224* *E1225* *E1226* *E1227* *E1228* *E1238* *E1250* *E1251* *E1252* *E1253* - *E1256* *E1297* + *E1256* *E1297* *E1298* Types are checked for most builtin functions to make it easier to spot mistakes. diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -3318,5 +3318,9 @@ EXTERN char e_cannot_specify_both_type_a EXTERN char e_can_only_use_left_padding_when_column_is_zero[] INIT(= N_("E1296: Can only use left padding when column is zero")); #endif +#ifdef FEAT_EVAL EXTERN char e_non_null_dict_required_for_argument_nr[] INIT(= N_("E1297: Non-NULL Dictionary required for argument %d")); +EXTERN char e_non_null_list_required_for_argument_nr[] + INIT(= N_("E1298: Non-NULL List required for argument %d")); +#endif diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -3235,11 +3235,8 @@ f_call(typval_T *argvars, typval_T *rett || check_for_opt_dict_arg(argvars, 2) == FAIL)) return; - if (argvars[1].v_type != VAR_LIST) - { - emsg(_(e_list_required)); - return; - } + if (check_for_list_arg(argvars, 1) == FAIL) + return; if (argvars[1].vval.v_list == NULL) return; diff --git a/src/filepath.c b/src/filepath.c --- a/src/filepath.c +++ b/src/filepath.c @@ -1603,19 +1603,20 @@ readdir_checkitem(void *context, void *i return checkitem_common(context, name, NULL); } +/* + * Process the keys in the Dict argument to the readdir() and readdirex() + * functions. Assumes the Dict argument is the 3rd argument. + */ static int -readdirex_dict_arg(typval_T *tv, int *cmp) +readdirex_dict_arg(typval_T *argvars, int *cmp) { char_u *compare; - if (tv->v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 2) == FAIL) return FAIL; - } - - if (dict_has_key(tv->vval.v_dict, "sort")) - compare = dict_get_string(tv->vval.v_dict, "sort", FALSE); + + if (dict_has_key(argvars[2].vval.v_dict, "sort")) + compare = dict_get_string(argvars[2].vval.v_dict, "sort", FALSE); else { semsg(_(e_dictionary_key_str_required), "sort"); @@ -1660,7 +1661,7 @@ f_readdir(typval_T *argvars, typval_T *r expr = &argvars[1]; if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN && - readdirex_dict_arg(&argvars[2], &sort) == FAIL) + readdirex_dict_arg(argvars, &sort) == FAIL) return; ret = readdir_core(&ga, path, FALSE, (void *)expr, @@ -1713,7 +1714,7 @@ f_readdirex(typval_T *argvars, typval_T expr = &argvars[1]; if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN && - readdirex_dict_arg(&argvars[2], &sort) == FAIL) + readdirex_dict_arg(argvars, &sort) == FAIL) return; ret = readdir_core(&ga, path, TRUE, (void *)expr, diff --git a/src/insexpand.c b/src/insexpand.c --- a/src/insexpand.c +++ b/src/insexpand.c @@ -2930,9 +2930,7 @@ f_complete(typval_T *argvars, typval_T * if (!undo_allowed()) return; - if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) - emsg(_(e_invalid_argument)); - else + if (check_for_nonnull_list_arg(argvars, 1) != FAIL) { startcol = (int)tv_get_number_chk(&argvars[0], NULL); if (startcol > 0) @@ -3143,11 +3141,8 @@ f_complete_info(typval_T *argvars, typva if (argvars[0].v_type != VAR_UNKNOWN) { - if (argvars[0].v_type != VAR_LIST) - { - emsg(_(e_list_required)); + if (check_for_list_arg(argvars, 0) == FAIL) return; - } what_list = argvars[0].vval.v_list; } get_complete_info(what_list, rettv->vval.v_dict); diff --git a/src/list.c b/src/list.c --- a/src/list.c +++ b/src/list.c @@ -1519,11 +1519,8 @@ f_join(typval_T *argvars, typval_T *rett || check_for_opt_string_arg(argvars, 1) == FAIL)) return; - if (argvars[0].v_type != VAR_LIST) - { - emsg(_(e_list_required)); + if (check_for_list_arg(argvars, 0) == FAIL) return; - } if (argvars[0].vval.v_list == NULL) return; @@ -1728,11 +1725,8 @@ f_list2str(typval_T *argvars, typval_T * || check_for_opt_bool_arg(argvars, 1) == FAIL)) return; - if (argvars[0].v_type != VAR_LIST) - { - emsg(_(e_invalid_argument)); + if (check_for_list_arg(argvars, 0) == FAIL) return; - } l = argvars[0].vval.v_list; if (l == NULL) diff --git a/src/match.c b/src/match.c --- a/src/match.c +++ b/src/match.c @@ -1087,11 +1087,8 @@ f_setmatches(typval_T *argvars UNUSED, t || check_for_opt_number_arg(argvars, 1) == FAIL)) return; - if (argvars[0].v_type != VAR_LIST) - { - emsg(_(e_list_required)); + if (check_for_list_arg(argvars, 0) == FAIL) return; - } win = get_optional_window(argvars, 1); if (win == NULL) return; diff --git a/src/mbyte.c b/src/mbyte.c --- a/src/mbyte.c +++ b/src/mbyte.c @@ -5535,14 +5535,9 @@ f_setcellwidths(typval_T *argvars, typva size_t cw_table_size_save; char *error = NULL; - if (in_vim9script() && check_for_list_arg(argvars, 0) == FAIL) + if (check_for_nonnull_list_arg(argvars, 0) == FAIL) return; - if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) - { - emsg(_(e_list_required)); - return; - } l = argvars[0].vval.v_list; if (l->lv_len == 0) { diff --git a/src/proto/typval.pro b/src/proto/typval.pro --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -20,6 +20,7 @@ int check_for_bool_arg(typval_T *args, i int check_for_opt_bool_arg(typval_T *args, int idx); int check_for_blob_arg(typval_T *args, int idx); int check_for_list_arg(typval_T *args, int idx); +int check_for_nonnull_list_arg(typval_T *args, int idx); int check_for_opt_list_arg(typval_T *args, int idx); int check_for_dict_arg(typval_T *args, int idx); int check_for_nonnull_dict_arg(typval_T *args, int idx); diff --git a/src/sign.c b/src/sign.c --- a/src/sign.c +++ b/src/sign.c @@ -2660,11 +2660,8 @@ f_sign_placelist(typval_T *argvars, typv if (in_vim9script() && check_for_list_arg(argvars, 0) == FAIL) return; - if (argvars[0].v_type != VAR_LIST) - { - emsg(_(e_list_required)); + if (check_for_list_arg(argvars, 0) == FAIL) return; - } // Process the List of sign attributes FOR_ALL_LIST_ITEMS(argvars[0].vval.v_list, li) @@ -2888,11 +2885,8 @@ f_sign_unplacelist(typval_T *argvars, ty if (in_vim9script() && check_for_list_arg(argvars, 0) == FAIL) return; - if (argvars[0].v_type != VAR_LIST) - { - emsg(_(e_list_required)); + if (check_for_list_arg(argvars, 0) == FAIL) return; - } FOR_ALL_LIST_ITEMS(argvars[0].vval.v_list, li) { diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -6462,11 +6462,9 @@ f_term_setansicolors(typval_T *argvars, if (term->tl_vterm == NULL) return; - if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) - { - emsg(_(e_list_required)); + if (check_for_nonnull_list_arg(argvars, 1) == FAIL) return; - } + if (argvars[1].vval.v_list->lv_first == &range_list_item || argvars[1].vval.v_list->lv_len != 16) { diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -2244,9 +2244,12 @@ func Test_readdir_sort() exe "lang collate" collate " 5) Errors - call assert_fails('call readdir(dir, 1, 1)', 'E715:') + call assert_fails('call readdir(dir, 1, 1)', 'E1206:') call assert_fails('call readdir(dir, 1, #{sorta: 1})') + call assert_fails('call readdir(dir, 1, test_null_dict())', 'E1297:') + call assert_fails('call readdirex(dir, 1, 1)', 'E1206:') call assert_fails('call readdirex(dir, 1, #{sorta: 1})') + call assert_fails('call readdirex(dir, 1, test_null_dict())', 'E1297:') " 6) ignore other values in dict let files = readdir(dir, '1', #{sort: 'c'}) @@ -2285,7 +2288,7 @@ endfunc func Test_call() call assert_equal(3, call('len', [123])) call assert_equal(3, 'len'->call([123])) - call assert_fails("call call('len', 123)", 'E714:') + call assert_fails("call call('len', 123)", 'E1211:') call assert_equal(0, call('', [])) call assert_equal(0, call('len', test_null_list())) @@ -2580,7 +2583,7 @@ func Test_range() " list2str() call assert_equal('ABC', list2str(range(65, 67))) - call assert_fails('let s = list2str(5)', 'E474:') + call assert_fails('let s = list2str(5)', 'E1211:') " lock() let thelist = range(5) diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -673,14 +673,14 @@ func Test_complete_func_error() func ListColors() call complete(col('.'), "blue") endfunc - call assert_fails('exe "normal i\=ListColors()\"', 'E474:') + call assert_fails('exe "normal i\=ListColors()\"', 'E1211:') func ListMonths() call complete(col('.'), test_null_list()) endfunc - call assert_fails('exe "normal i\=ListMonths()\"', 'E474:') + call assert_fails('exe "normal i\=ListMonths()\"', 'E1298:') delfunc ListColors delfunc ListMonths - call assert_fails('call complete_info({})', 'E714:') + call assert_fails('call complete_info({})', 'E1211:') call assert_equal([], complete_info(['items']).items) endfunc diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim --- a/src/testdir/test_match.vim +++ b/src/testdir/test_match.vim @@ -95,7 +95,7 @@ function Test_match() call assert_equal(0, setmatches([])) call assert_equal(0, setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])) call clearmatches() - call assert_fails('call setmatches(0)', 'E714:') + call assert_fails('call setmatches(0)', 'E1211:') call assert_fails('call setmatches([0])', 'E474:') call assert_fails("call setmatches([{'wrong key': 'wrong value'}])", 'E474:') call assert_equal(-1, setmatches([{'group' : 'Search', 'priority' : 10, 'id' : 5, 'pos1' : {}}])) diff --git a/src/testdir/test_method.vim b/src/testdir/test_method.vim --- a/src/testdir/test_method.vim +++ b/src/testdir/test_method.vim @@ -52,7 +52,7 @@ func Test_dict_method() call assert_fails("let x = d->insert(0)", 'E899:') call assert_true(d->has_key('two')) call assert_equal([['one', 1], ['two', 2], ['three', 3]], d->items()) - call assert_fails("let x = d->join()", 'E714:') + call assert_fails("let x = d->join()", 'E1211:') call assert_equal(['one', 'two', 'three'], d->keys()) call assert_equal(3, d->len()) call assert_equal(#{one: 2, two: 3, three: 4}, d->map('v:val + 1')) diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim --- a/src/testdir/test_signs.vim +++ b/src/testdir/test_signs.vim @@ -2010,7 +2010,7 @@ func Test_sign_funcs_multi() " Invalid arguments call assert_equal([], sign_placelist([])) - call assert_fails('call sign_placelist({})', "E714:") + call assert_fails('call sign_placelist({})', "E1211:") call assert_fails('call sign_placelist([[]])', "E715:") call assert_fails('call sign_placelist(["abc"])', "E715:") call assert_fails('call sign_placelist([100])', "E715:") @@ -2021,7 +2021,7 @@ func Test_sign_funcs_multi() " Invalid arguments call assert_equal([], []->sign_unplacelist()) - call assert_fails('call sign_unplacelist({})', "E714:") + call assert_fails('call sign_unplacelist({})', "E1211:") call assert_fails('call sign_unplacelist([[]])', "E715:") call assert_fails('call sign_unplacelist(["abc"])', "E715:") call assert_fails('call sign_unplacelist([100])', "E715:") diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -2065,7 +2065,7 @@ func Test_terminal_ansicolors_func() let colors[4] = 'Invalid' call assert_fails('call term_setansicolors(buf, colors)', 'E254:') - call assert_fails('call term_setansicolors(buf, {})', 'E714:') + call assert_fails('call term_setansicolors(buf, {})', 'E1211:') set tgc& call StopShellInTerminal(buf) diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -381,7 +381,7 @@ func Test_prop_add_list() call assert_fails('call prop_add_list(#{type: "one"}, [[2, 2, 2, 2], [3, 20, 3, 22]])', 'E964:') call assert_fails('eval #{type: "one"}->prop_add_list([[2, 2, 2, 2], [3, 20, 3, 22]])', 'E964:') call assert_fails('call prop_add_list(test_null_dict(), [[2, 2, 2]])', 'E965:') - call assert_fails('call prop_add_list(#{type: "one"}, test_null_list())', 'E714:') + call assert_fails('call prop_add_list(#{type: "one"}, test_null_list())', 'E1298:') call assert_fails('call prop_add_list(#{type: "one"}, [test_null_list()])', 'E714:') call DeletePropTypes() bw! diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim --- a/src/testdir/test_utf8.vim +++ b/src/testdir/test_utf8.vim @@ -168,7 +168,7 @@ func Test_setcellwidths() call setcellwidths([]) - call assert_fails('call setcellwidths(1)', 'E714:') + call assert_fails('call setcellwidths(1)', 'E1211:') call assert_fails('call setcellwidths([1, 2, 0])', 'E1109:') diff --git a/src/textprop.c b/src/textprop.c --- a/src/textprop.c +++ b/src/textprop.c @@ -348,11 +348,8 @@ f_prop_add_list(typval_T *argvars, typva || check_for_list_arg(argvars, 1) == FAIL) return; - if (argvars[1].vval.v_list == NULL) - { - emsg(_(e_list_required)); + if (check_for_nonnull_list_arg(argvars, 1) == FAIL) return; - } dict = argvars[0].vval.v_dict; if (dict == NULL || !dict_has_key(dict, "type")) diff --git a/src/typval.c b/src/typval.c --- a/src/typval.c +++ b/src/typval.c @@ -509,6 +509,23 @@ check_for_list_arg(typval_T *args, int i } /* + * Give an error and return FAIL unless "args[idx]" is a non-NULL list. + */ + int +check_for_nonnull_list_arg(typval_T *args, int idx) +{ + if (check_for_list_arg(args, idx) == FAIL) + return FAIL; + + if (args[idx].vval.v_list == NULL) + { + semsg(_(e_non_null_list_required_for_argument_nr), idx + 1); + return FAIL; + } + return OK; +} + +/* * Check for an optional list argument at 'idx' */ int diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -708,6 +708,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 345, +/**/ 344, /**/ 343,