# HG changeset patch # User Bram Moolenaar # Date 1665316803 -7200 # Node ID ec54b510e5eecba7f527d7a942b5060248bc62ba # Parent 78482941c68c46bf5552b1c8feb864ec8465b076 patch 9.0.0703: failing check for argument type for const any Commit: https://github.com/vim/vim/commit/330d64d32cbb8ba7cdfe8dc0bedd4caff3bb01e8 Author: Bram Moolenaar Date: Sun Oct 9 12:55:33 2022 +0100 patch 9.0.0703: failing check for argument type for const any Problem: Failing check for argument type for const any. Solution: Check for any type properly. (closes https://github.com/vim/vim/issues/11316) diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -257,10 +257,9 @@ arg_type_modifiable(type_T *type, int ar static int arg_float_or_nr(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_FLOAT - || type->tt_type == VAR_NUMBER) + if (type->tt_type == VAR_FLOAT + || type->tt_type == VAR_NUMBER + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_number, type, context->arg_idx + 1); return FAIL; @@ -356,10 +355,9 @@ arg_bool(type_T *type, type_T *decl_type static int arg_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_LIST - || type->tt_type == VAR_BLOB) + if (type->tt_type == VAR_LIST + || type->tt_type == VAR_BLOB + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); return FAIL; @@ -385,10 +383,9 @@ arg_list_or_blob_mod( static int arg_string_or_nr(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING - || type->tt_type == VAR_NUMBER) + if (type->tt_type == VAR_STRING + || type->tt_type == VAR_NUMBER + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -400,10 +397,9 @@ arg_string_or_nr(type_T *type, type_T *d static int arg_buffer(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING - || type->tt_type == VAR_NUMBER) + if (type->tt_type == VAR_STRING + || type->tt_type == VAR_NUMBER + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -415,11 +411,10 @@ arg_buffer(type_T *type, type_T *decl_ty static int arg_buffer_or_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING + if (type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER - || type->tt_type == VAR_DICT) + || type->tt_type == VAR_DICT + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -431,10 +426,9 @@ arg_buffer_or_dict_any(type_T *type, typ static int arg_lnum(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING - || type->tt_type == VAR_NUMBER) + if (type->tt_type == VAR_STRING + || type->tt_type == VAR_NUMBER + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -446,9 +440,8 @@ arg_lnum(type_T *type, type_T *decl_type static int arg_string_or_list_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING) + if (type->tt_type == VAR_STRING + || type_any_or_unknown(type)) return OK; if (type->tt_type != VAR_LIST) { @@ -469,10 +462,9 @@ arg_string_or_list_string(type_T *type, static int arg_string_or_list_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING - || type->tt_type == VAR_LIST) + if (type->tt_type == VAR_STRING + || type->tt_type == VAR_LIST + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -484,10 +476,9 @@ arg_string_or_list_any(type_T *type, typ static int arg_string_or_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING - || type->tt_type == VAR_DICT) + if (type->tt_type == VAR_STRING + || type->tt_type == VAR_DICT + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -499,10 +490,9 @@ arg_string_or_dict_any(type_T *type, typ static int arg_string_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING - || type->tt_type == VAR_BLOB) + if (type->tt_type == VAR_STRING + || type->tt_type == VAR_BLOB + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -514,10 +504,9 @@ arg_string_or_blob(type_T *type, type_T static int arg_list_or_dict(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_LIST - || type->tt_type == VAR_DICT) + if (type->tt_type == VAR_LIST + || type->tt_type == VAR_DICT + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); return FAIL; @@ -547,11 +536,10 @@ arg_list_or_dict_or_blob_mod( type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_LIST + if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT - || type->tt_type == VAR_BLOB) + || type->tt_type == VAR_BLOB + || type_any_or_unknown(type)) return arg_type_modifiable(type, context->arg_idx + 1); arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); return FAIL; @@ -563,12 +551,11 @@ arg_list_or_dict_or_blob_mod( static int arg_list_or_dict_or_blob_or_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_LIST + if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT || type->tt_type == VAR_BLOB - || type->tt_type == VAR_STRING) + || type->tt_type == VAR_STRING + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); return FAIL; @@ -642,15 +629,13 @@ check_map_filter_arg2(type_T *type, argc } } - if ((type->tt_member != &t_any && type->tt_member != &t_unknown) - || args[0] != NULL) + if (!type_any_or_unknown(type->tt_member) || args[0] != NULL) { where_T where = WHERE_INIT; if (is_map) t_func_exp.tt_member = expected_member == NULL - || type->tt_member == &t_any - || type->tt_member == &t_unknown + || type_any_or_unknown(type->tt_member) ? &t_any : expected_member; else t_func_exp.tt_member = &t_bool; @@ -673,8 +658,7 @@ arg_filter_func(type_T *type, type_T *de { if (type->tt_type == VAR_STRING || type->tt_type == VAR_PARTIAL - || type == &t_unknown - || type == &t_any) + || type_any_or_unknown(type)) return OK; if (type->tt_type == VAR_FUNC) @@ -691,8 +675,7 @@ arg_map_func(type_T *type, type_T *decl_ { if (type->tt_type == VAR_STRING || type->tt_type == VAR_PARTIAL - || type == &t_unknown - || type == &t_any) + || type_any_or_unknown(type)) return OK; if (type->tt_type == VAR_FUNC) @@ -709,8 +692,7 @@ arg_sort_how(type_T *type, type_T *decl_ { if (type->tt_type == VAR_STRING || type->tt_type == VAR_PARTIAL - || type == &t_unknown - || type == &t_any) + || type_any_or_unknown(type)) return OK; if (type->tt_type == VAR_FUNC) @@ -722,8 +704,7 @@ arg_sort_how(type_T *type, type_T *decl_ args[0] = context->arg_types[0].type_curr->tt_member; else args[0] = &t_unknown; - if ((type->tt_member != &t_any && type->tt_member != &t_unknown) - || args[0] != &t_unknown) + if (!type_any_or_unknown(type->tt_member) || args[0] != &t_unknown) { where_T where = WHERE_INIT; @@ -748,13 +729,12 @@ arg_sort_how(type_T *type, type_T *decl_ static int arg_string_or_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING + if (type->tt_type == VAR_STRING || type->tt_type == VAR_PARTIAL || type->tt_type == VAR_FUNC || type->tt_type == VAR_BOOL - || type->tt_type == VAR_NUMBER) + || type->tt_type == VAR_NUMBER + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_func_any, type, context->arg_idx + 1); return FAIL; @@ -766,11 +746,10 @@ arg_string_or_func(type_T *type, type_T static int arg_string_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_LIST + if (type->tt_type == VAR_LIST || type->tt_type == VAR_BLOB - || type->tt_type == VAR_STRING) + || type->tt_type == VAR_STRING + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); return FAIL; @@ -791,10 +770,9 @@ arg_job(type_T *type, type_T *decl_type static int arg_chan_or_job(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_CHANNEL - || type->tt_type == VAR_JOB) + if (type->tt_type == VAR_CHANNEL + || type->tt_type == VAR_JOB + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_channel, type, context->arg_idx + 1); return FAIL; @@ -854,11 +832,10 @@ arg_item_of_prev(type_T *type, type_T *d static int arg_str_or_nr_or_list(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING + if (type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER - || type->tt_type == VAR_LIST) + || type->tt_type == VAR_LIST + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -870,10 +847,9 @@ arg_str_or_nr_or_list(type_T *type, type static int arg_dict_any_or_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_DICT - || type->tt_type == VAR_STRING) + if (type->tt_type == VAR_DICT + || type->tt_type == VAR_STRING + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); return FAIL; @@ -902,13 +878,12 @@ arg_extend3(type_T *type, type_T *decl_t static int arg_get1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_BLOB + if (type->tt_type == VAR_BLOB || type->tt_type == VAR_LIST || type->tt_type == VAR_DICT || type->tt_type == VAR_FUNC - || type->tt_type == VAR_PARTIAL) + || type->tt_type == VAR_PARTIAL + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); @@ -922,13 +897,12 @@ arg_get1(type_T *type, type_T *decl_type static int arg_len1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING + if (type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER || type->tt_type == VAR_BLOB || type->tt_type == VAR_LIST - || type->tt_type == VAR_DICT) + || type->tt_type == VAR_DICT + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); @@ -958,12 +932,11 @@ arg_remove2(type_T *type, type_T *decl_t static int arg_repeat1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING + if (type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER || type->tt_type == VAR_BLOB - || type->tt_type == VAR_LIST) + || type->tt_type == VAR_LIST + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_string, type, context->arg_idx + 1); @@ -977,11 +950,10 @@ arg_repeat1(type_T *type, type_T *decl_t static int arg_slice1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_LIST + if (type->tt_type == VAR_LIST || type->tt_type == VAR_BLOB - || type->tt_type == VAR_STRING) + || type->tt_type == VAR_STRING + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); @@ -995,11 +967,10 @@ arg_slice1(type_T *type, type_T *decl_ty static int arg_string_or_list_or_dict(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_STRING + if (type->tt_type == VAR_STRING || type->tt_type == VAR_LIST - || type->tt_type == VAR_DICT) + || type->tt_type == VAR_DICT + || type_any_or_unknown(type)) return OK; semsg(_(e_string_list_or_dict_required_for_argument_nr), @@ -1014,11 +985,10 @@ arg_string_or_list_or_dict(type_T *type, static int arg_cursor1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { - if (type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN - || type->tt_type == VAR_NUMBER + if (type->tt_type == VAR_NUMBER || type->tt_type == VAR_STRING - || type->tt_type == VAR_LIST) + || type->tt_type == VAR_LIST + || type_any_or_unknown(type)) return OK; arg_type_mismatch(&t_number, type, context->arg_idx + 1); diff --git a/src/proto/vim9type.pro b/src/proto/vim9type.pro --- a/src/proto/vim9type.pro +++ b/src/proto/vim9type.pro @@ -9,6 +9,7 @@ type_T *get_dict_type(type_T *member_typ type_T *alloc_func_type(type_T *ret_type, int argcount, garray_T *type_gap); type_T *get_func_type(type_T *ret_type, int argcount, garray_T *type_gap); int func_type_add_arg_types(type_T *functype, int argcount, garray_T *type_gap); +int type_any_or_unknown(type_T *type); int need_convert_to_bool(type_T *type, typval_T *tv); type_T *typval2type(typval_T *tv, int copyID, garray_T *type_gap, int flags); type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap); diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -305,6 +305,25 @@ def Test_const() assert_equal(v:t_number, type(foo.bar)) END v9.CheckDefAndScriptSuccess(lines) + + # also when used as a builtin function argument + lines =<< trim END + vim9script + + def SorterFunc(lhs: dict, rhs: dict): number + return lhs.name <# rhs.name ? -1 : 1 + enddef + + def Run(): void + var list = [{name: "3"}, {name: "2"}] + const Sorter = get({}, "unknown", SorterFunc) + sort(list, Sorter) + assert_equal([{name: "2"}, {name: "3"}], list) + enddef + + Run() + END + v9.CheckScriptSuccess(lines) enddef def Test_const_bang() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -700,6 +700,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 703, +/**/ 702, /**/ 701, diff --git a/src/vim9type.c b/src/vim9type.c --- a/src/vim9type.c +++ b/src/vim9type.c @@ -337,6 +337,17 @@ func_type_add_arg_types( } /* + * Return TRUE if "type" is NULL, any or unknown. + * This also works for const (comparing with &t_any and &t_unknown doesn't). + */ + int +type_any_or_unknown(type_T *type) +{ + return type == NULL || type->tt_type == VAR_ANY + || type->tt_type == VAR_UNKNOWN; +} + +/* * Get a type_T for a typval_T. * "type_gap" is used to temporarily create types in. * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use