To: vim_dev@googlegroups.com Subject: Patch 9.0.1108 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1108 Problem: Type error when using "any" type and adding a number to a float. Solution: Accept both a number and a float. (closes #11753) Files: src/vim9compile.c, src/proto/vim9compile.pro, src/structs.h, src/vim9instr.c, src/proto/vim9instr.pro, src/vim9cmds.c, src/evalfunc.c, src/vim9expr.c, src/vim9type.c, src/vim9execute.c, src/testdir/test_vim9_expr.vim *** ../vim-9.0.1107/src/vim9compile.c 2022-12-23 17:56:21.405511534 +0000 --- src/vim9compile.c 2022-12-29 20:15:50.625658518 +0000 *************** *** 451,456 **** --- 451,457 ---- need_type_where( type_T *actual, type_T *expected, + int number_ok, // expect VAR_FLOAT but VAR_NUMBER is OK int offset, where_T where, cctx_T *cctx, *************** *** 480,486 **** // If the actual type can be the expected type add a runtime check. if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected)) { ! generate_TYPECHECK(cctx, expected, offset, where.wt_variable, where.wt_index); return OK; } --- 481,487 ---- // If the actual type can be the expected type add a runtime check. if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected)) { ! generate_TYPECHECK(cctx, expected, number_ok, offset, where.wt_variable, where.wt_index); return OK; } *************** *** 494,499 **** --- 495,501 ---- need_type( type_T *actual, type_T *expected, + int number_ok, // when expected is float number is also OK int offset, int arg_idx, cctx_T *cctx, *************** *** 503,509 **** where_T where = WHERE_INIT; where.wt_index = arg_idx; ! return need_type_where(actual, expected, offset, where, cctx, silent, actual_is_const); } --- 505,511 ---- where_T where = WHERE_INIT; where.wt_index = arg_idx; ! return need_type_where(actual, expected, number_ok, offset, where, cctx, silent, actual_is_const); } *************** *** 2000,2007 **** // now we can properly check the type if (rhs_type != NULL && lhs->lhs_type->tt_member != NULL && rhs_type != &t_void ! && need_type(rhs_type, lhs->lhs_type->tt_member, -2, 0, cctx, ! FALSE, FALSE) == FAIL) return FAIL; } else --- 2002,2009 ---- // now we can properly check the type if (rhs_type != NULL && lhs->lhs_type->tt_member != NULL && rhs_type != &t_void ! && need_type(rhs_type, lhs->lhs_type->tt_member, FALSE, ! -2, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } else *************** *** 2090,2102 **** if (range) { type = get_type_on_stack(cctx, 1); ! if (need_type(type, &t_number, -2, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } type = get_type_on_stack(cctx, 0); if ((dest_type != VAR_BLOB && type->tt_type != VAR_SPECIAL) ! && need_type(type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } --- 2092,2104 ---- if (range) { type = get_type_on_stack(cctx, 1); ! if (need_type(type, &t_number, FALSE, -2, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } type = get_type_on_stack(cctx, 0); if ((dest_type != VAR_BLOB && type->tt_type != VAR_SPECIAL) ! && need_type(type, &t_number, FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } *************** *** 2357,2363 **** emsg(_(e_cannot_use_void_value)); goto theend; } ! if (need_type(stacktype, &t_list_any, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; // If a constant list was used we can check the length right here. --- 2359,2365 ---- emsg(_(e_cannot_use_void_value)); goto theend; } ! if (need_type(stacktype, &t_list_any, FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; // If a constant list was used we can check the length right here. *************** *** 2424,2430 **** { SOURCING_LNUM = start_lnum; if (lhs.lhs_has_type ! && need_type(&t_list_string, lhs.lhs_type, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; } --- 2426,2432 ---- { SOURCING_LNUM = start_lnum; if (lhs.lhs_has_type ! && need_type(&t_list_string, lhs.lhs_type, FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; } *************** *** 2549,2556 **** && !has_list_index(var_start + lhs.lhs_varlen, cctx)) use_type = lhs.lhs_member_type; ! if (need_type_where(rhs_type, use_type, -1, where, ! cctx, FALSE, is_const) == FAIL) goto theend; } } --- 2551,2558 ---- && !has_list_index(var_start + lhs.lhs_varlen, cctx)) use_type = lhs.lhs_member_type; ! if (need_type_where(rhs_type, use_type, FALSE, -1, ! where, cctx, FALSE, is_const) == FAIL) goto theend; } } *************** *** 2565,2571 **** || lhs_type == &t_float) && rhs_type->tt_type == VAR_NUMBER) lhs_type = &t_number; ! if (*p != '=' && need_type(rhs_type, lhs_type, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; } --- 2567,2573 ---- || lhs_type == &t_float) && rhs_type->tt_type == VAR_NUMBER) lhs_type = &t_number; ! if (*p != '=' && need_type(rhs_type, lhs_type, FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; } *************** *** 2622,2629 **** if ( // If variable is float operation with number is OK. !(expected == &t_float && (stacktype == &t_number ! || stacktype == &t_number_bool)) && ! need_type(stacktype, expected, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; } --- 2624,2631 ---- if ( // If variable is float operation with number is OK. !(expected == &t_float && (stacktype == &t_number ! || stacktype == &t_number_bool)) ! && need_type(stacktype, expected, TRUE, -1, 0, cctx, FALSE, FALSE) == FAIL) goto theend; } *************** *** 3104,3110 **** ufunc->uf_arg_types[arg_idx] = val_type; } else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx], ! -1, where, &cctx, FALSE, FALSE) == FAIL) goto erret; if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL) --- 3106,3112 ---- ufunc->uf_arg_types[arg_idx] = val_type; } else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx], ! FALSE, -1, where, &cctx, FALSE, FALSE) == FAIL) goto erret; if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL) *** ../vim-9.0.1107/src/proto/vim9compile.pro 2022-09-14 00:30:47.077316538 +0100 --- src/proto/vim9compile.pro 2022-12-29 20:17:52.749562784 +0000 *************** *** 5,13 **** int script_is_vim9(void); int script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack); int check_defined(char_u *p, size_t len, cctx_T *cctx, cstack_T *cstack, int is_arg); ! int need_type_where(type_T *actual, type_T *expected, int offset, where_T where, cctx_T *cctx, int silent, int actual_is_const); ! int need_type(type_T *actual, type_T *expected, int offset, int arg_idx, cctx_T *cctx, int silent, int actual_is_const); ! lvar_T *reserve_local(cctx_T *cctx, char_u *name, size_t len, int isConst, type_T *type); int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx, cstack_T *cstack); imported_T *find_imported(char_u *name, size_t len, int load); char_u *may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp); --- 5,13 ---- int script_is_vim9(void); int script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack); int check_defined(char_u *p, size_t len, cctx_T *cctx, cstack_T *cstack, int is_arg); ! int need_type_where(type_T *actual, type_T *expected, int number_ok, int offset, where_T where, cctx_T *cctx, int silent, int actual_is_const); ! int need_type(type_T *actual, type_T *expected, int number_ok, int offset, int arg_idx, cctx_T *cctx, int silent, int actual_is_const); ! lvar_T *reserve_local(cctx_T *cctx, char_u *name, size_t len, int assign, type_T *type); int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx, cstack_T *cstack); imported_T *find_imported(char_u *name, size_t len, int load); char_u *may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp); *** ../vim-9.0.1107/src/structs.h 2022-12-18 21:42:49.010716927 +0000 --- src/structs.h 2022-12-29 20:05:44.254184012 +0000 *************** *** 1460,1465 **** --- 1460,1471 ---- type_T *type_decl; // declared type or equal to type_current } type2_T; + #define TTFLAG_VARARGS 0x01 // func args ends with "..." + #define TTFLAG_BOOL_OK 0x02 // can be converted to bool + #define TTFLAG_NUMBER_OK 0x04 // tt_type is VAR_FLOAT, VAR_NUMBER is OK + #define TTFLAG_STATIC 0x08 // one of the static types, e.g. t_any + #define TTFLAG_CONST 0x10 // cannot be changed + typedef enum { ACCESS_PRIVATE, // read/write only inside th class ACCESS_READ, // read everywhere, write only inside th class *************** *** 1517,1527 **** int obj_copyID; // used by garbage collection }; - #define TTFLAG_VARARGS 0x01 // func args ends with "..." - #define TTFLAG_BOOL_OK 0x02 // can be converted to bool - #define TTFLAG_STATIC 0x04 // one of the static types, e.g. t_any - #define TTFLAG_CONST 0x08 // cannot be changed - /* * Structure to hold an internal variable without a name. */ --- 1523,1528 ---- *** ../vim-9.0.1107/src/vim9instr.c 2022-12-18 22:01:38.869926641 +0000 --- src/vim9instr.c 2022-12-29 20:46:40.946278300 +0000 *************** *** 576,581 **** --- 576,582 ---- generate_TYPECHECK( cctx_T *cctx, type_T *expected, + int number_ok, // add TTFLAG_NUMBER_OK flag int offset, int is_var, int argidx) *************** *** 585,591 **** RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL) return FAIL; ! isn->isn_arg.type.ct_type = alloc_type(expected); isn->isn_arg.type.ct_off = (int8_T)offset; isn->isn_arg.type.ct_is_var = is_var; isn->isn_arg.type.ct_arg_idx = (int8_T)argidx; --- 586,606 ---- RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL) return FAIL; ! type_T *tt; ! if (expected->tt_type == VAR_FLOAT && number_ok) ! { ! // always allocate, also for static types ! tt = ALLOC_ONE(type_T); ! if (tt != NULL) ! { ! *tt = *expected; ! tt->tt_flags |= TTFLAG_NUMBER_OK; ! } ! } ! else ! tt = alloc_type(expected); ! ! isn->isn_arg.type.ct_type = tt; isn->isn_arg.type.ct_off = (int8_T)offset; isn->isn_arg.type.ct_is_var = is_var; isn->isn_arg.type.ct_arg_idx = (int8_T)argidx; *************** *** 1601,1607 **** if (maptype != NULL && maptype[0].type_decl->tt_member != NULL && maptype[0].type_decl->tt_member != &t_any) // Check that map() didn't change the item types. ! generate_TYPECHECK(cctx, maptype[0].type_decl, -1, FALSE, 1); return OK; } --- 1616,1622 ---- if (maptype != NULL && maptype[0].type_decl->tt_member != NULL && maptype[0].type_decl->tt_member != &t_any) // Check that map() didn't change the item types. ! generate_TYPECHECK(cctx, maptype[0].type_decl, FALSE, -1, FALSE, 1); return OK; } *************** *** 1625,1631 **** return FAIL; item_type = get_type_on_stack(cctx, 0); expected = list_type->tt_member; ! if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; if (generate_instr(cctx, ISN_LISTAPPEND) == NULL) --- 1640,1646 ---- return FAIL; item_type = get_type_on_stack(cctx, 0); expected = list_type->tt_member; ! if (need_type(item_type, expected, FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; if (generate_instr(cctx, ISN_LISTAPPEND) == NULL) *************** *** 1648,1654 **** if (arg_type_modifiable(get_decl_type_on_stack(cctx, 1), 1) == FAIL) return FAIL; item_type = get_type_on_stack(cctx, 0); ! if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL) --- 1663,1670 ---- if (arg_type_modifiable(get_decl_type_on_stack(cctx, 1), 1) == FAIL) return FAIL; item_type = get_type_on_stack(cctx, 0); ! if (need_type(item_type, &t_number, FALSE, ! -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL) *************** *** 1713,1720 **** expected = &t_any; else expected = ufunc->uf_va_type->tt_member; ! if (need_type(actual, expected, -argcount + i, i + 1, cctx, ! TRUE, FALSE) == FAIL) { arg_type_mismatch(expected, actual, i + 1); return FAIL; --- 1729,1736 ---- expected = &t_any; else expected = ufunc->uf_va_type->tt_member; ! if (need_type(actual, expected, FALSE, ! -argcount + i, i + 1, cctx, TRUE, FALSE) == FAIL) { arg_type_mismatch(expected, actual, i + 1); return FAIL; *************** *** 1821,1828 **** expected = &t_any; else expected = type->tt_args[i]; ! if (need_type(actual, expected, offset, i + 1, ! cctx, TRUE, FALSE) == FAIL) { arg_type_mismatch(expected, actual, i + 1); return FAIL; --- 1837,1844 ---- expected = &t_any; else expected = type->tt_args[i]; ! if (need_type(actual, expected, FALSE, ! offset, i + 1, cctx, TRUE, FALSE) == FAIL) { arg_type_mismatch(expected, actual, i + 1); return FAIL; *** ../vim-9.0.1107/src/proto/vim9instr.pro 2022-12-18 21:42:49.014716925 +0000 --- src/proto/vim9instr.pro 2022-12-29 20:09:27.981976958 +0000 *************** *** 15,21 **** int generate_CONCAT(cctx_T *cctx, int count); int generate_2BOOL(cctx_T *cctx, int invert, int offset); int generate_COND2BOOL(cctx_T *cctx); ! int generate_TYPECHECK(cctx_T *cctx, type_T *expected, int offset, int is_var, int argidx); int generate_SETTYPE(cctx_T *cctx, type_T *expected); int generate_tv_PUSH(cctx_T *cctx, typval_T *tv); int generate_PUSHNR(cctx_T *cctx, varnumber_T number); --- 15,21 ---- int generate_CONCAT(cctx_T *cctx, int count); int generate_2BOOL(cctx_T *cctx, int invert, int offset); int generate_COND2BOOL(cctx_T *cctx); ! int generate_TYPECHECK(cctx_T *cctx, type_T *expected, int number_ok, int offset, int is_var, int argidx); int generate_SETTYPE(cctx_T *cctx, type_T *expected); int generate_tv_PUSH(cctx_T *cctx, typval_T *tv); int generate_PUSHNR(cctx_T *cctx, varnumber_T number); *** ../vim-9.0.1107/src/vim9cmds.c 2022-12-25 15:59:19.993863341 +0000 --- src/vim9cmds.c 2022-12-29 20:14:12.365737240 +0000 *************** *** 1045,1051 **** if (lhs_type == &t_any) lhs_type = item_type; else if (item_type != &t_unknown ! && need_type_where(item_type, lhs_type, -1, where, cctx, FALSE, FALSE) == FAIL) goto failed; var_lvar = reserve_local(cctx, arg, varlen, ASSIGN_FINAL, --- 1045,1051 ---- if (lhs_type == &t_any) lhs_type = item_type; else if (item_type != &t_unknown ! && need_type_where(item_type, lhs_type, FALSE, -1, where, cctx, FALSE, FALSE) == FAIL) goto failed; var_lvar = reserve_local(cctx, arg, varlen, ASSIGN_FINAL, *************** *** 2469,2475 **** if (compile_assign_lhs(arg, lhs, CMD_redir, FALSE, FALSE, FALSE, 1, cctx) == FAIL) return NULL; ! if (need_type(&t_string, lhs->lhs_member_type, -1, 0, cctx, FALSE, FALSE) == FAIL) return NULL; if (cctx->ctx_skip == SKIP_YES) --- 2469,2475 ---- if (compile_assign_lhs(arg, lhs, CMD_redir, FALSE, FALSE, FALSE, 1, cctx) == FAIL) return NULL; ! if (need_type(&t_string, lhs->lhs_member_type, FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) return NULL; if (cctx->ctx_skip == SKIP_YES) *************** *** 2551,2557 **** int save_flags = cmdmod.cmod_flags; generate_LEGACY_EVAL(cctx, p); ! if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, -1, 0, cctx, FALSE, FALSE) == FAIL) return NULL; cmdmod.cmod_flags |= CMOD_LEGACY; --- 2551,2557 ---- int save_flags = cmdmod.cmod_flags; generate_LEGACY_EVAL(cctx, p); ! if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) return NULL; cmdmod.cmod_flags |= CMOD_LEGACY; *************** *** 2580,2587 **** } else { ! if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, ! 0, cctx, FALSE, FALSE) == FAIL) return NULL; } } --- 2580,2587 ---- } else { ! if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, FALSE, ! -1, 0, cctx, FALSE, FALSE) == FAIL) return NULL; } } *** ../vim-9.0.1107/src/evalfunc.c 2022-12-20 20:01:09.620090910 +0000 --- src/evalfunc.c 2022-12-29 20:13:38.857764490 +0000 *************** *** 215,221 **** type_T *actual, argcontext_T *context) { ! return need_type(actual, expected, context->arg_idx - context->arg_count, context->arg_idx + 1, context->arg_cctx, FALSE, FALSE); } --- 215,221 ---- type_T *actual, argcontext_T *context) { ! return need_type(actual, expected, FALSE, context->arg_idx - context->arg_count, context->arg_idx + 1, context->arg_cctx, FALSE, FALSE); } *************** *** 229,235 **** type_T *actual, argcontext_T *context) { ! if (need_type(actual, expected, context->arg_idx - context->arg_count, context->arg_idx + 1, context->arg_cctx, FALSE, FALSE) == FAIL) return FAIL; --- 229,235 ---- type_T *actual, argcontext_T *context) { ! if (need_type(actual, expected, FALSE, context->arg_idx - context->arg_count, context->arg_idx + 1, context->arg_cctx, FALSE, FALSE) == FAIL) return FAIL; *** ../vim-9.0.1107/src/vim9expr.c 2022-12-27 20:54:35.940837899 +0000 --- src/vim9expr.c 2022-12-29 20:17:04.665600223 +0000 *************** *** 99,111 **** vartype = VAR_DICT; if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB) { ! if (need_type(idxtype, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; if (is_slice) { idxtype = get_type_on_stack(cctx, 1); ! if (need_type(idxtype, &t_number, -2, 0, cctx, ! FALSE, FALSE) == FAIL) return FAIL; } } --- 99,112 ---- vartype = VAR_DICT; if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB) { ! if (need_type(idxtype, &t_number, FALSE, ! -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; if (is_slice) { idxtype = get_type_on_stack(cctx, 1); ! if (need_type(idxtype, &t_number, FALSE, ! -2, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } } *************** *** 135,142 **** } else { ! if (need_type(typep->type_curr, &t_dict_any, -2, 0, cctx, ! FALSE, FALSE) == FAIL) return FAIL; typep->type_curr = &t_any; typep->type_decl = &t_any; --- 136,143 ---- } else { ! if (need_type(typep->type_curr, &t_dict_any, FALSE, ! -2, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; typep->type_curr = &t_any; typep->type_decl = &t_any; *************** *** 1725,1731 **** // This requires a runtime type check. return generate_COND2BOOL(cctx); ! return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE); } /* --- 1726,1732 ---- // This requires a runtime type check. return generate_COND2BOOL(cctx); ! return need_type(type, &t_bool, FALSE, -1, 0, cctx, FALSE, FALSE); } /* *************** *** 1759,1765 **** { type_T *type = get_type_on_stack(cctx, 0); if (type->tt_type != VAR_FLOAT && need_type(type, &t_number, ! -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; // only '-' has an effect, for '+' we only check the type --- 1760,1766 ---- { type_T *type = get_type_on_stack(cctx, 0); if (type->tt_type != VAR_FLOAT && need_type(type, &t_number, ! FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; // only '-' has an effect, for '+' we only check the type *************** *** 2517,2524 **** actual = get_type_on_stack(cctx, 0); if (check_type_maybe(want_type, actual, FALSE, where) != OK) { ! if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) ! == FAIL) return FAIL; } } --- 2518,2525 ---- actual = get_type_on_stack(cctx, 0); if (check_type_maybe(want_type, actual, FALSE, where) != OK) { ! if (need_type(actual, want_type, FALSE, ! -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } } *************** *** 2759,2765 **** { type_T *t = get_type_on_stack(cctx, 0); ! if (need_type(t, &t_number, 0, 0, cctx, FALSE, FALSE) == FAIL) { emsg(_(e_bitshift_ops_must_be_number)); return FAIL; --- 2760,2766 ---- { type_T *t = get_type_on_stack(cctx, 0); ! if (need_type(t, &t_number, FALSE, 0, 0, cctx, FALSE, FALSE) == FAIL) { emsg(_(e_bitshift_ops_must_be_number)); return FAIL; *************** *** 2814,2821 **** } else { ! if (need_type(get_type_on_stack(cctx, 0), &t_number, 0, 0, cctx, ! FALSE, FALSE) == FAIL) { emsg(_(e_bitshift_ops_must_be_number)); return FAIL; --- 2815,2822 ---- } else { ! if (need_type(get_type_on_stack(cctx, 0), &t_number, FALSE, ! 0, 0, cctx, FALSE, FALSE) == FAIL) { emsg(_(e_bitshift_ops_must_be_number)); return FAIL; *** ../vim-9.0.1107/src/vim9type.c 2022-12-27 17:24:55.270083348 +0000 --- src/vim9type.c 2022-12-29 20:22:52.737334749 +0000 *************** *** 813,818 **** --- 813,823 ---- && (actual->tt_flags & TTFLAG_BOOL_OK)) // Using number 0 or 1 for bool is OK. return OK; + if (expected->tt_type == VAR_FLOAT + && (expected->tt_flags & TTFLAG_NUMBER_OK) + && actual->tt_type == VAR_NUMBER) + // Using number where float is expected is OK here. + return OK; if (give_msg) type_mismatch_where(expected, actual, where); return FAIL; *************** *** 848,854 **** { int i; ! for (i = 0; i < expected->tt_argcount && i < actual->tt_argcount; ++i) // Allow for using "any" argument type, lambda's have them. if (actual->tt_args[i] != &t_any && check_type( expected->tt_args[i], actual->tt_args[i], FALSE, --- 853,860 ---- { int i; ! for (i = 0; i < expected->tt_argcount ! && i < actual->tt_argcount; ++i) // Allow for using "any" argument type, lambda's have them. if (actual->tt_args[i] != &t_any && check_type( expected->tt_args[i], actual->tt_args[i], FALSE, *** ../vim-9.0.1107/src/vim9execute.c 2022-12-24 21:23:59.578929527 +0000 --- src/vim9execute.c 2022-12-29 20:30:10.752199871 +0000 *************** *** 6872,6887 **** case ISN_CHECKTYPE: { checktype_T *ct = &iptr->isn_arg.type; ! char *tofree; if (ct->ct_arg_idx == 0) smsg("%s%4d CHECKTYPE %s stack[%d]", pfx, current, ! type_name(ct->ct_type, &tofree), (int)ct->ct_off); else smsg("%s%4d CHECKTYPE %s stack[%d] %s %d", pfx, current, ! type_name(ct->ct_type, &tofree), (int)ct->ct_off, ct->ct_is_var ? "var": "arg", (int)ct->ct_arg_idx); --- 6872,6894 ---- case ISN_CHECKTYPE: { checktype_T *ct = &iptr->isn_arg.type; ! char *tofree = NULL; ! char *typename; ! ! if (ct->ct_type->tt_type == VAR_FLOAT ! && (ct->ct_type->tt_flags & TTFLAG_NUMBER_OK)) ! typename = "float|number"; ! else ! typename = type_name(ct->ct_type, &tofree); if (ct->ct_arg_idx == 0) smsg("%s%4d CHECKTYPE %s stack[%d]", pfx, current, ! typename, (int)ct->ct_off); else smsg("%s%4d CHECKTYPE %s stack[%d] %s %d", pfx, current, ! typename, (int)ct->ct_off, ct->ct_is_var ? "var": "arg", (int)ct->ct_arg_idx); *** ../vim-9.0.1107/src/testdir/test_vim9_expr.vim 2022-12-27 20:54:35.940837899 +0000 --- src/testdir/test_vim9_expr.vim 2022-12-29 20:40:49.182807310 +0000 *************** *** 2033,2038 **** --- 2033,2066 ---- v9.CheckScriptFailure(['vim9script', "var x = "], 'E15:', 2) v9.CheckDefAndScriptFailure(["var x = 123"], 'E1068:', 1) v9.CheckDefAndScriptFailure(["var x = v + return sum + enddef + + const kk = 1 + Sum(kk) + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected float but got number') enddef " test low level expression *** ../vim-9.0.1107/src/version.c 2022-12-27 20:54:35.940837899 +0000 --- src/version.c 2022-12-29 20:47:22.626221016 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1108, /**/ -- ARTHUR: No, hang on! Just answer the five questions ... GALAHAD: Three questions ... ARTHUR: Three questions ... And we shall watch ... and pray. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// 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 ///