To: vim_dev@googlegroups.com Subject: Patch 8.2.3994 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3994 Problem: Vim9: extend() complains about the type even when it was not declared. Solution: Only check the list or dict type when it was declared. Files: src/list.c, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.3993/src/list.c 2022-01-03 12:27:59.359039951 +0000 --- src/list.c 2022-01-03 15:01:35.340002252 +0000 *************** *** 2758,2782 **** extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new) { type_T *type = NULL; - garray_T type_list; char *func_name = is_new ? "extendnew()" : "extend()"; - if (!is_new && in_vim9script()) - { - // Check that extend() does not change the type of the dict. - ga_init2(&type_list, sizeof(type_T *), 10); - type = typval2type(argvars, get_copyID(), &type_list, TVTT_DO_MEMBER); - } - if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) list_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv); else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) dict_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv); else semsg(_(e_argument_of_str_must_be_list_or_dictionary), func_name); - - if (type != NULL) - clear_type_list(&type_list); } /* --- 2758,2783 ---- extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new) { type_T *type = NULL; char *func_name = is_new ? "extendnew()" : "extend()"; if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) + { + // Check that extend() does not change the type of the list if it was + // declared. + if (!is_new && in_vim9script() && argvars[0].vval.v_list != NULL) + type = argvars[0].vval.v_list->lv_type; list_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv); + } else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) + { + // Check that extend() does not change the type of the list if it was + // declared. + if (!is_new && in_vim9script() && argvars[0].vval.v_dict != NULL) + type = argvars[0].vval.v_dict->dv_type; dict_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv); + } else semsg(_(e_argument_of_str_must_be_list_or_dictionary), func_name); } /* *** ../vim-8.2.3993/src/testdir/test_vim9_builtin.vim 2022-01-03 12:27:59.359039951 +0000 --- src/testdir/test_vim9_builtin.vim 2022-01-03 16:46:52.361229193 +0000 *************** *** 974,988 **** assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, 'keep')) assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, g:string_keep)) var res: list> extend(res, mapnew([1, 2], (_, v) => ({}))) assert_equal([{}, {}], res) END CheckDefAndScriptSuccess(lines) CheckDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type mismatch, expected list but got string', 'E712: Argument of extend() must be a List or Dictionary']) CheckDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type mismatch, expected list but got number', 'E712: Argument of extend() must be a List or Dictionary']) ! CheckDefAndScriptFailure(['extend([1, 2], ["x"])'], ['E1013: Argument 2: type mismatch, expected list but got list', 'E1013: Argument 2: type mismatch, expected list but got list']) CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string') CheckDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, expected dict but got number') --- 974,998 ---- assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, 'keep')) assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, g:string_keep)) + # mix of types is OK without a declaration + var res: list> extend(res, mapnew([1, 2], (_, v) => ({}))) assert_equal([{}, {}], res) END CheckDefAndScriptSuccess(lines) + # FIXME: this should not fail when compiled + lines =<< trim END + vim9script + assert_equal([1, 2, "x"], extend([1, 2], ["x"])) + assert_equal([1, "b", 1], extend([1], ["b", 1])) + END + CheckScriptSuccess(lines) + CheckDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type mismatch, expected list but got string', 'E712: Argument of extend() must be a List or Dictionary']) CheckDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type mismatch, expected list but got number', 'E712: Argument of extend() must be a List or Dictionary']) ! CheckDefAndScriptFailure(['var ll = [1, 2]', 'extend(ll, ["x"])'], ['E1013: Argument 2: type mismatch, expected list but got list', 'E1013: Argument 2: type mismatch, expected list but got list']) CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string') CheckDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, expected dict but got number') *************** *** 992,998 **** CheckDefFailure(['extend([1], ["b"])'], 'E1013: Argument 2: type mismatch, expected list but got list') CheckDefExecFailure(['extend([1], ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list but got list') ! CheckScriptFailure(['vim9script', 'extend([1], ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list but got list in extend()') enddef func g:ExtendDict(d) --- 1002,1008 ---- CheckDefFailure(['extend([1], ["b"])'], 'E1013: Argument 2: type mismatch, expected list but got list') CheckDefExecFailure(['extend([1], ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list but got list') ! CheckScriptFailure(['vim9script', 'var l = [1]', 'extend(l, ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list but got list in extend()') enddef func g:ExtendDict(d) *** ../vim-8.2.3993/src/version.c 2022-01-03 13:47:45.960911768 +0000 --- src/version.c 2022-01-03 15:02:50.267822777 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 3994, /**/ -- hundred-and-one symptoms of being an internet addict: 210. When you get a divorce, you don't care about who gets the children, but discuss endlessly who can use the email address. /// 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 ///