To: vim_dev@googlegroups.com Subject: Patch 8.2.0820 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0820 Problem: Vim9: function type isn't set until compiled. Solution: Set function type early. Files: src/vim9compile.c, src/proto/vim9compile.pro, src/userfunc.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.0819/src/vim9compile.c 2020-05-24 23:00:06.444196001 +0200 --- src/vim9compile.c 2020-05-24 23:37:21.634564583 +0200 *************** *** 6763,6816 **** ufunc->uf_flags |= FC_CLOSURE; } - { - int varargs = ufunc->uf_va_name != NULL; - int argcount = ufunc->uf_args.ga_len; - - // Create a type for the function, with the return type and any - // argument types. - // A vararg is included in uf_args.ga_len but not in uf_arg_types. - // The type is included in "tt_args". - if (argcount > 0 || varargs) - { - ufunc->uf_func_type = alloc_func_type(ufunc->uf_ret_type, - argcount, &ufunc->uf_type_list); - // Add argument types to the function type. - if (func_type_add_arg_types(ufunc->uf_func_type, - argcount + varargs, - &ufunc->uf_type_list) == FAIL) - { - ret = FAIL; - goto erret; - } - ufunc->uf_func_type->tt_argcount = argcount + varargs; - ufunc->uf_func_type->tt_min_argcount = - argcount - ufunc->uf_def_args.ga_len; - if (ufunc->uf_arg_types == NULL) - { - int i; - - // lambda does not have argument types. - for (i = 0; i < argcount; ++i) - ufunc->uf_func_type->tt_args[i] = &t_any; - } - else - mch_memmove(ufunc->uf_func_type->tt_args, - ufunc->uf_arg_types, sizeof(type_T *) * argcount); - if (varargs) - { - ufunc->uf_func_type->tt_args[argcount] = - ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type; - ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS; - } - } - else - // No arguments, can use a predefined type. - ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type, - argcount, &ufunc->uf_type_list); - - } - ret = OK; erret: --- 6763,6768 ---- *************** *** 6847,6852 **** --- 6799,6851 ---- return ret; } + void + set_function_type(ufunc_T *ufunc) + { + int varargs = ufunc->uf_va_name != NULL; + int argcount = ufunc->uf_args.ga_len; + + // Create a type for the function, with the return type and any + // argument types. + // A vararg is included in uf_args.ga_len but not in uf_arg_types. + // The type is included in "tt_args". + if (argcount > 0 || varargs) + { + ufunc->uf_func_type = alloc_func_type(ufunc->uf_ret_type, + argcount, &ufunc->uf_type_list); + // Add argument types to the function type. + if (func_type_add_arg_types(ufunc->uf_func_type, + argcount + varargs, + &ufunc->uf_type_list) == FAIL) + return; + ufunc->uf_func_type->tt_argcount = argcount + varargs; + ufunc->uf_func_type->tt_min_argcount = + argcount - ufunc->uf_def_args.ga_len; + if (ufunc->uf_arg_types == NULL) + { + int i; + + // lambda does not have argument types. + for (i = 0; i < argcount; ++i) + ufunc->uf_func_type->tt_args[i] = &t_any; + } + else + mch_memmove(ufunc->uf_func_type->tt_args, + ufunc->uf_arg_types, sizeof(type_T *) * argcount); + if (varargs) + { + ufunc->uf_func_type->tt_args[argcount] = + ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type; + ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS; + } + } + else + // No arguments, can use a predefined type. + ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type, + argcount, &ufunc->uf_type_list); + } + + /* * Delete an instruction, free what it contains. */ *** ../vim-8.2.0819/src/proto/vim9compile.pro 2020-05-24 23:00:06.444196001 +0200 --- src/proto/vim9compile.pro 2020-05-24 23:37:23.174560943 +0200 *************** *** 10,15 **** --- 10,16 ---- int assignment_len(char_u *p, int *heredoc); int check_vim9_unlet(char_u *name); int compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx); + void set_function_type(ufunc_T *ufunc); void delete_instr(isn_T *isn); void delete_def_function(ufunc_T *ufunc); void free_def_functions(void); *** ../vim-8.2.0819/src/userfunc.c 2020-05-24 23:00:06.440196016 +0200 --- src/userfunc.c 2020-05-24 23:38:22.242420368 +0200 *************** *** 3284,3289 **** --- 3284,3292 ---- is_export = FALSE; } + if (eap->cmdidx == CMD_def) + set_function_type(fp); + goto ret_free; erret: *** ../vim-8.2.0819/src/testdir/test_vim9_func.vim 2020-05-24 23:00:06.444196001 +0200 --- src/testdir/test_vim9_func.vim 2020-05-24 23:39:07.442311631 +0200 *************** *** 560,567 **** RefVoid = FuncNoArgNoRet RefVoid = FuncOneArgNoRet CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') ! " TODO: these should fail ! " CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') let RefAny: func(): any RefAny = FuncNoArgRetNumber --- 560,566 ---- RefVoid = FuncNoArgNoRet RefVoid = FuncOneArgNoRet CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') ! CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') let RefAny: func(): any RefAny = FuncNoArgRetNumber *************** *** 573,580 **** RefNr = FuncNoArgRetNumber RefNr = FuncOneArgRetNumber CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') ! " TODO: should fail ! " CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') let RefStr: func: string RefStr = FuncNoArgRetString --- 572,578 ---- RefNr = FuncNoArgRetNumber RefNr = FuncOneArgRetNumber CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') ! CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') let RefStr: func: string RefStr = FuncNoArgRetString *************** *** 589,598 **** CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') ! " TODO: these don't fail ! " CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)') ! " CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)') ! " CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)') call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') --- 587,595 ---- CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') ! CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)') ! CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)') ! CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)') call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') *** ../vim-8.2.0819/src/version.c 2020-05-24 23:14:20.053504523 +0200 --- src/version.c 2020-05-24 23:37:05.554602524 +0200 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 820, /**/ -- If Apple would build a car... ... it would be powered by the sun, be reliable, five times as fast and twice as easy to drive; but would only run on five percent of the roads. /// 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 ///