To: vim_dev@googlegroups.com Subject: Patch 9.0.1224 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1224 Problem: Cannot call a :def function with a number for a float argument. Solution: Accept a number as well, convert it to a float. Files: src/vim9type.c, src/globals.h, src/vim9execute.c, src/structs.h, src/testdir/test_vim9_func.vim *** ../vim-9.0.1223/src/vim9type.c 2023-01-16 16:39:33.491018024 +0000 --- src/vim9type.c 2023-01-20 18:32:46.034812447 +0000 *************** *** 628,639 **** { type_T *type = typval2type_int(tv, copyID, type_gap, flags); ! if (type != NULL && type != &t_bool ! && (tv->v_type == VAR_NUMBER && (tv->vval.v_number == 0 || tv->vval.v_number == 1))) ! // Number 0 and 1 and expression with "&&" or "||" can also be used for ! // bool. ! type = &t_number_bool; return type; } --- 628,644 ---- { type_T *type = typval2type_int(tv, copyID, type_gap, flags); ! if (type != NULL) ! { ! if (type != &t_bool && (tv->v_type == VAR_NUMBER && (tv->vval.v_number == 0 || tv->vval.v_number == 1))) ! // Number 0 and 1 and expression with "&&" or "||" can also be used ! // for bool. ! type = &t_number_bool; ! else if (type != &t_float && tv->v_type == VAR_NUMBER) ! // A number can also be used for float. ! type = &t_number_float; ! } return type; } *************** *** 821,829 **** // 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); --- 826,835 ---- // Using number 0 or 1 for bool is OK. return OK; if (expected->tt_type == VAR_FLOAT ! && actual->tt_type == VAR_NUMBER ! && ((expected->tt_flags & TTFLAG_NUMBER_OK) ! || (actual->tt_flags & TTFLAG_FLOAT_OK))) ! // Using a number where a float is expected is OK here. return OK; if (give_msg) type_mismatch_where(expected, actual, where); *** ../vim-9.0.1223/src/globals.h 2023-01-14 11:46:09.704717821 +0000 --- src/globals.h 2023-01-20 17:43:39.470115266 +0000 *************** *** 430,536 **** #define t_number_bool (static_types[14]) #define t_const_number_bool (static_types[15]) ! #define t_float (static_types[16]) ! #define t_const_float (static_types[17]) ! #define t_string (static_types[18]) ! #define t_const_string (static_types[19]) ! #define t_blob (static_types[20]) ! #define t_const_blob (static_types[21]) ! #define t_blob_null (static_types[22]) ! #define t_const_blob_null (static_types[23]) ! #define t_job (static_types[24]) ! #define t_const_job (static_types[25]) ! #define t_channel (static_types[26]) ! #define t_const_channel (static_types[27]) // t_number_or_string - Special value used for @#. ! #define t_number_or_string (static_types[28]) ! #define t_const_number_or_string (static_types[29]) // t_func_unknown - function with any arguments and no or unknown return value ! #define t_func_unknown (static_types[30]) ! #define t_const_func_unknown (static_types[31]) // t_func_void - function with any arguments and no return value ! #define t_func_void (static_types[32]) ! #define t_const_func_void (static_types[33]) ! #define t_func_any (static_types[34]) ! #define t_const_func_any (static_types[35]) ! #define t_func_number (static_types[36]) ! #define t_const_func_number (static_types[37]) ! #define t_func_string (static_types[38]) ! #define t_const_func_string (static_types[39]) ! #define t_func_bool (static_types[40]) ! #define t_const_func_bool (static_types[41]) // t_func_0_void - function without arguments and nor return value ! #define t_func_0_void (static_types[42]) ! #define t_const_func_0_void (static_types[43]) ! #define t_func_0_any (static_types[44]) ! #define t_const_func_0_any (static_types[45]) ! #define t_func_0_number (static_types[46]) ! #define t_const_func_0_number (static_types[47]) ! #define t_func_0_string (static_types[48]) ! #define t_const_func_0_string (static_types[49]) ! #define t_list_any (static_types[50]) ! #define t_const_list_any (static_types[51]) ! #define t_dict_any (static_types[52]) ! #define t_const_dict_any (static_types[53]) ! #define t_list_empty (static_types[54]) ! #define t_const_list_empty (static_types[55]) ! #define t_dict_empty (static_types[56]) ! #define t_const_dict_empty (static_types[57]) ! #define t_list_bool (static_types[58]) ! #define t_const_list_bool (static_types[59]) ! #define t_list_number (static_types[60]) ! #define t_const_list_number (static_types[61]) ! #define t_list_string (static_types[62]) ! #define t_const_list_string (static_types[63]) ! #define t_list_job (static_types[64]) ! #define t_const_list_job (static_types[65]) ! #define t_list_dict_any (static_types[66]) ! #define t_const_list_dict_any (static_types[67]) ! #define t_list_list_any (static_types[68]) ! #define t_const_list_list_any (static_types[69]) ! #define t_list_list_string (static_types[70]) ! #define t_const_list_list_string (static_types[71]) ! #define t_dict_bool (static_types[72]) ! #define t_const_dict_bool (static_types[73]) ! #define t_dict_number (static_types[74]) ! #define t_const_dict_number (static_types[75]) ! #define t_dict_string (static_types[76]) ! #define t_const_dict_string (static_types[77]) ! #define t_super (static_types[78]) ! #define t_const_super (static_types[79]) ! EXTERN type_T static_types[80] #ifdef DO_INIT = { // 0: t_unknown --- 430,540 ---- #define t_number_bool (static_types[14]) #define t_const_number_bool (static_types[15]) ! // t_number_float - number that can be used as a float ! #define t_number_float (static_types[16]) ! #define t_const_number_float (static_types[17]) ! #define t_float (static_types[18]) ! #define t_const_float (static_types[19]) ! #define t_string (static_types[20]) ! #define t_const_string (static_types[21]) ! #define t_blob (static_types[22]) ! #define t_const_blob (static_types[23]) ! #define t_blob_null (static_types[24]) ! #define t_const_blob_null (static_types[25]) ! #define t_job (static_types[26]) ! #define t_const_job (static_types[27]) ! ! #define t_channel (static_types[28]) ! #define t_const_channel (static_types[29]) // t_number_or_string - Special value used for @#. ! #define t_number_or_string (static_types[30]) ! #define t_const_number_or_string (static_types[31]) // t_func_unknown - function with any arguments and no or unknown return value ! #define t_func_unknown (static_types[32]) ! #define t_const_func_unknown (static_types[33]) // t_func_void - function with any arguments and no return value ! #define t_func_void (static_types[34]) ! #define t_const_func_void (static_types[35]) ! #define t_func_any (static_types[36]) ! #define t_const_func_any (static_types[37]) ! #define t_func_number (static_types[38]) ! #define t_const_func_number (static_types[39]) ! #define t_func_string (static_types[40]) ! #define t_const_func_string (static_types[41]) ! #define t_func_bool (static_types[42]) ! #define t_const_func_bool (static_types[43]) // t_func_0_void - function without arguments and nor return value ! #define t_func_0_void (static_types[44]) ! #define t_const_func_0_void (static_types[45]) ! #define t_func_0_any (static_types[46]) ! #define t_const_func_0_any (static_types[47]) ! #define t_func_0_number (static_types[48]) ! #define t_const_func_0_number (static_types[49]) ! #define t_func_0_string (static_types[50]) ! #define t_const_func_0_string (static_types[51]) ! #define t_list_any (static_types[52]) ! #define t_const_list_any (static_types[53]) ! #define t_dict_any (static_types[54]) ! #define t_const_dict_any (static_types[55]) ! #define t_list_empty (static_types[56]) ! #define t_const_list_empty (static_types[57]) ! #define t_dict_empty (static_types[58]) ! #define t_const_dict_empty (static_types[59]) ! #define t_list_bool (static_types[60]) ! #define t_const_list_bool (static_types[61]) ! #define t_list_number (static_types[62]) ! #define t_const_list_number (static_types[63]) ! #define t_list_string (static_types[64]) ! #define t_const_list_string (static_types[65]) ! #define t_list_job (static_types[66]) ! #define t_const_list_job (static_types[67]) ! #define t_list_dict_any (static_types[68]) ! #define t_const_list_dict_any (static_types[69]) ! #define t_list_list_any (static_types[70]) ! #define t_const_list_list_any (static_types[71]) ! #define t_list_list_string (static_types[72]) ! #define t_const_list_list_string (static_types[73]) ! #define t_dict_bool (static_types[74]) ! #define t_const_dict_bool (static_types[75]) ! #define t_dict_number (static_types[76]) ! #define t_const_dict_number (static_types[77]) ! #define t_dict_string (static_types[78]) ! #define t_const_dict_string (static_types[79]) ! #define t_super (static_types[80]) ! #define t_const_super (static_types[81]) ! EXTERN type_T static_types[82] #ifdef DO_INIT = { // 0: t_unknown *************** *** 565,695 **** {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK, NULL, NULL}, {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK|TTFLAG_CONST, NULL, NULL}, ! // 16: t_float {VAR_FLOAT, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_FLOAT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 18: t_string {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 20: t_blob {VAR_BLOB, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 22: t_blob_null {VAR_BLOB, 0, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, ! // 24: t_job {VAR_JOB, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_JOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 26: t_channel {VAR_CHANNEL, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_CHANNEL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 28: t_number_or_string {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 30: t_func_unknown {VAR_FUNC, -1, -1, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_FUNC, -1, -1, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, ! // 32: t_func_void {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, ! // 34: t_func_any {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 36: t_func_number {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 38: t_func_string {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 40: t_func_bool {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, ! // 42: t_func_0_void {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, ! // 44: t_func_0_any {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 46: t_func_0_number {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 48: t_func_0_string {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 50: t_list_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 52: t_dict_any {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 54: t_list_empty {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, ! // 56: t_dict_empty {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, ! // 58: t_list_bool {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, ! // 60: t_list_number {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 62: t_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 64: t_list_job {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_job, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_job, NULL}, ! // 66: t_list_dict_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_dict_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_dict_any, NULL}, ! // 68: t_list_list_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL}, ! // 70: t_list_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL}, ! // 72: t_dict_bool {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, ! // 74: t_dict_number {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 76: t_dict_string {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 78: t_super (VAR_CLASS with tt_member set to &t_bool {VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, } --- 569,703 ---- {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK, NULL, NULL}, {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK|TTFLAG_CONST, NULL, NULL}, ! // 16: t_number_float ! {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK, NULL, NULL}, ! {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK|TTFLAG_CONST, NULL, NULL}, ! ! // 18: t_float {VAR_FLOAT, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_FLOAT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 20: t_string {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 22: t_blob {VAR_BLOB, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 24: t_blob_null {VAR_BLOB, 0, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, ! // 26: t_job {VAR_JOB, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_JOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 28: t_channel {VAR_CHANNEL, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_CHANNEL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 30: t_number_or_string {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, ! // 32: t_func_unknown {VAR_FUNC, -1, -1, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_FUNC, -1, -1, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, ! // 34: t_func_void {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, ! // 36: t_func_any {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 38: t_func_number {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 40: t_func_string {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 42: t_func_bool {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, ! // 44: t_func_0_void {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, ! // 46: t_func_0_any {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 48: t_func_0_number {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 50: t_func_0_string {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 52: t_list_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 54: t_dict_any {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, ! // 56: t_list_empty {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, ! // 58: t_dict_empty {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, ! // 60: t_list_bool {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, ! // 62: t_list_number {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 64: t_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 66: t_list_job {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_job, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_job, NULL}, ! // 68: t_list_dict_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_dict_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_dict_any, NULL}, ! // 70: t_list_list_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL}, ! // 72: t_list_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL}, ! // 74: t_dict_bool {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, ! // 76: t_dict_number {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, ! // 78: t_dict_string {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, ! // 80: t_super (VAR_CLASS with tt_member set to &t_bool {VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, } *** ../vim-9.0.1223/src/vim9execute.c 2023-01-16 20:47:53.889287080 +0000 --- src/vim9execute.c 2023-01-20 18:34:54.394881461 +0000 *************** *** 5822,5833 **** } else { ! if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len ! && check_typval_arg_type( ! ufunc->uf_arg_types[idx], tv, NULL, argv_idx + 1) == FAIL) ! goto failed_early; ! copy_tv(tv, STACK_TV_BOT(0)); } ++ectx.ec_stack.ga_len; } --- 5822,5846 ---- } else { ! int done = FALSE; ! if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len) ! { ! type_T *expected = ufunc->uf_arg_types[idx]; ! if (expected->tt_type == VAR_FLOAT && tv->v_type == VAR_NUMBER) ! { ! // When a float is expected and a number was given, convert ! // the value. ! STACK_TV_BOT(0)->v_type = VAR_FLOAT; ! STACK_TV_BOT(0)->v_lock = 0; ! STACK_TV_BOT(0)->vval.v_float = tv->vval.v_number; ! done = TRUE; ! } ! else if (check_typval_arg_type(expected, tv, NULL, argv_idx + 1) == FAIL) ! goto failed_early; ! } ! if (!done) ! copy_tv(tv, STACK_TV_BOT(0)); } ++ectx.ec_stack.ga_len; } *** ../vim-9.0.1223/src/structs.h 2023-01-16 19:43:43.390873675 +0000 --- src/structs.h 2023-01-20 18:36:35.102928179 +0000 *************** *** 1462,1471 **** #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 ! #define TTFLAG_SUPER 0x20 // object from "super". typedef enum { ACCESS_PRIVATE, // read/write only inside th class --- 1462,1472 ---- #define TTFLAG_VARARGS 0x01 // func args ends with "..." #define TTFLAG_BOOL_OK 0x02 // can be converted to bool ! #define TTFLAG_FLOAT_OK 0x04 // number can be used/converted to float ! #define TTFLAG_NUMBER_OK 0x08 // number can be used for a float ! #define TTFLAG_STATIC 0x10 // one of the static types, e.g. t_any ! #define TTFLAG_CONST 0x20 // cannot be changed ! #define TTFLAG_SUPER 0x40 // object from "super". typedef enum { ACCESS_PRIVATE, // read/write only inside th class *** ../vim-9.0.1223/src/testdir/test_vim9_func.vim 2023-01-03 12:33:23.082974364 +0000 --- src/testdir/test_vim9_func.vim 2023-01-20 18:19:20.413874054 +0000 *************** *** 727,732 **** --- 727,744 ---- v9.CheckScriptSuccess(lines) enddef + def Test_convert_number_to_float() + var lines =<< trim END + vim9script + def Foo(a: float, b: float): float + return a + b + enddef + + assert_equal(5.3, Foo(3.3, 2)) + END + v9.CheckScriptSuccess(lines) + enddef + def s:FuncWithComment( # comment a: number, #comment b: bool, # comment *************** *** 4311,4320 **** return sum enddef ! const ml = [3.0, 2, 7] echo Scan(ml)->Sum() END ! v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got number') enddef def Test_multiple_funcref() --- 4323,4332 ---- return sum enddef ! const ml = [3.0, 2, '7'] echo Scan(ml)->Sum() END ! v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string') enddef def Test_multiple_funcref() *** ../vim-9.0.1223/src/version.c 2023-01-20 16:00:49.542341277 +0000 --- src/version.c 2023-01-20 18:19:48.045931752 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1224, /**/ -- Due knot trussed yore spell chequer two fined awl miss steaks. /// 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 ///