To: vim_dev@googlegroups.com Subject: Patch 8.2.1996 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1996 Problem: Vim9: invalid error for argument of extend(). Solution: Check if the type could match. (closes #7299) Files: src/evalfunc.c, src/vim9compile.c, src/proto/vim9compile.pro, src/vim9type.c, src/proto/vim9type.pro, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.1995/src/evalfunc.c 2020-11-10 20:57:51.082004649 +0100 --- src/evalfunc.c 2020-11-16 20:06:10.616094468 +0100 *************** *** 295,301 **** static int arg_number(type_T *type, argcontext_T *context) { ! return check_type(&t_number, type, TRUE, context->arg_idx + 1); } /* --- 295,301 ---- static int arg_number(type_T *type, argcontext_T *context) { ! return check_arg_type(&t_number, type, context->arg_idx + 1); } /* *************** *** 304,310 **** static int arg_string(type_T *type, argcontext_T *context) { ! return check_type(&t_string, type, TRUE, context->arg_idx + 1); } /* --- 304,310 ---- static int arg_string(type_T *type, argcontext_T *context) { ! return check_arg_type(&t_string, type, context->arg_idx + 1); } /* *************** *** 342,348 **** { type_T *prev_type = context->arg_types[context->arg_idx - 1]; ! return check_type(prev_type, type, TRUE, context->arg_idx + 1); } /* --- 342,348 ---- { type_T *prev_type = context->arg_types[context->arg_idx - 1]; ! return check_arg_type(prev_type, type, context->arg_idx + 1); } /* *************** *** 363,369 **** // probably VAR_ANY, can't check return OK; ! return check_type(expected, type, TRUE, context->arg_idx + 1); } /* --- 363,369 ---- // probably VAR_ANY, can't check return OK; ! return check_arg_type(expected, type, context->arg_idx + 1); } /* *** ../vim-8.2.1995/src/vim9compile.c 2020-11-12 12:08:47.982254065 +0100 --- src/vim9compile.c 2020-11-16 19:49:59.822721071 +0100 *************** *** 820,826 **** * Return TRUE if "actual" could be "expected" and a runtime typecheck is to be * used. Return FALSE if the types will never match. */ ! static int use_typecheck(type_T *actual, type_T *expected) { if (actual->tt_type == VAR_ANY --- 820,826 ---- * Return TRUE if "actual" could be "expected" and a runtime typecheck is to be * used. Return FALSE if the types will never match. */ ! int use_typecheck(type_T *actual, type_T *expected) { if (actual->tt_type == VAR_ANY *** ../vim-8.2.1995/src/proto/vim9compile.pro 2020-10-15 12:46:38.733199522 +0200 --- src/proto/vim9compile.pro 2020-11-16 19:50:09.046697886 +0100 *************** *** 1,6 **** --- 1,7 ---- /* vim9compile.c */ int check_defined(char_u *p, size_t len, cctx_T *cctx); int check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2); + int use_typecheck(type_T *actual, type_T *expected); int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx); imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx); imported_T *find_imported_in_script(char_u *name, size_t len, int sid); *** ../vim-8.2.1995/src/vim9type.c 2020-11-04 12:00:46.656717337 +0100 --- src/vim9type.c 2020-11-16 20:01:59.772775191 +0100 *************** *** 517,522 **** --- 517,536 ---- } /* + * Like check_type() but also allow for a runtime type check. E.g. "any" can be + * used for "number". + */ + int + check_arg_type(type_T *expected, type_T *actual, int argidx) + { + if (check_type(expected, actual, FALSE, 0) == OK + || use_typecheck(actual, expected)) + return OK; + // TODO: should generate a TYPECHECK instruction. + return check_type(expected, actual, TRUE, argidx); + } + + /* * Skip over a type definition and return a pointer to just after it. * When "optional" is TRUE then a leading "?" is accepted. */ *** ../vim-8.2.1995/src/proto/vim9type.pro 2020-09-16 15:21:56.358720340 +0200 --- src/proto/vim9type.pro 2020-11-16 20:02:38.488669320 +0100 *************** *** 15,20 **** --- 15,21 ---- void type_mismatch(type_T *expected, type_T *actual); void arg_type_mismatch(type_T *expected, type_T *actual, int argidx); int check_type(type_T *expected, type_T *actual, int give_msg, int argidx); + int check_arg_type(type_T *expected, type_T *actual, int argidx); char_u *skip_type(char_u *start, int optional); type_T *parse_type(char_u **arg, garray_T *type_gap); void common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap); *** ../vim-8.2.1995/src/testdir/test_vim9_builtin.vim 2020-10-31 19:33:34.531695411 +0100 --- src/testdir/test_vim9_builtin.vim 2020-11-16 20:05:44.416165073 +0100 *************** *** 195,204 **** --- 195,210 ---- assert_equal([1, 2, 3], extend([1, 2], [3])) assert_equal([3, 1, 2], extend([1, 2], [3], 0)) assert_equal([1, 3, 2], extend([1, 2], [3], 1)) + assert_equal([1, 3, 2], extend([1, 2], [3], s:number_one)) assert_equal(#{a: 1, b: 2, c: 3}, extend(#{a: 1, b: 2}, #{c: 3})) assert_equal(#{a: 1, b: 4}, extend(#{a: 1, b: 2}, #{b: 4})) 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}, s:string_keep)) + + var res: list> + extend(res, map([1, 2], {_, v -> {}})) + assert_equal([{}, {}], res) CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, expected list but got number') CheckDefFailure(['extend([1, 2], ["x"])'], 'E1013: Argument 2: type mismatch, expected list but got list') *************** *** 338,343 **** --- 344,353 ---- index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) enddef + let s:number_one = 1 + let s:number_two = 2 + let s:string_keep = 'keep' + def Test_insert() var l = insert([2, 1], 3) var res = 0 *************** *** 347,355 **** --- 357,368 ---- res->assert_equal(6) assert_equal([1, 2, 3], insert([2, 3], 1)) + assert_equal([1, 2, 3], insert([2, 3], s:number_one)) assert_equal([1, 2, 3], insert([1, 2], 3, 2)) + assert_equal([1, 2, 3], insert([1, 2], 3, s:number_two)) assert_equal(['a', 'b', 'c'], insert(['b', 'c'], 'a')) assert_equal(0z1234, insert(0z34, 0x12)) + CheckDefFailure(['insert([2, 3], "a")'], 'E1013: Argument 2: type mismatch, expected number but got string', 1) CheckDefFailure(['insert([2, 3], 1, "x")'], 'E1013: Argument 3: type mismatch, expected number but got string', 1) enddef *** ../vim-8.2.1995/src/version.c 2020-11-16 19:11:44.807527909 +0100 --- src/version.c 2020-11-16 20:07:05.451947004 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 1996, /**/ -- hundred-and-one symptoms of being an internet addict: 255. You work for a newspaper and your editor asks you to write an article about Internet addiction...in the "first person." /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///