To: vim_dev@googlegroups.com Subject: Patch 8.2.1396 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1396 Problem: Vim9: no error for unexpectedly returning a value. Solution: Only set the return type for lambda's. Make using function type in a function reference work. Files: src/vim9compile.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.1395/src/vim9compile.c 2020-08-08 15:45:58.233358630 +0200 --- src/vim9compile.c 2020-08-08 16:45:40.219564173 +0200 *************** *** 662,669 **** int i; for (i = 0; i < expected->tt_argcount; ++i) ! if (check_type(expected->tt_args[i], actual->tt_args[i], ! FALSE) == FAIL) { ret = FAIL; break; --- 662,671 ---- int i; for (i = 0; i < expected->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) ! == FAIL) { ret = FAIL; break; *************** *** 1537,1543 **** * Generate an ISN_FUNCREF instruction. */ static int ! generate_FUNCREF(cctx_T *cctx, int dfunc_idx) { isn_T *isn; garray_T *stack = &cctx->ctx_type_stack; --- 1539,1545 ---- * Generate an ISN_FUNCREF instruction. */ static int ! generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc) { isn_T *isn; garray_T *stack = &cctx->ctx_type_stack; *************** *** 1545,1557 **** RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) return FAIL; ! isn->isn_arg.funcref.fr_func = dfunc_idx; isn->isn_arg.funcref.fr_var_idx = cctx->ctx_closure_count++; if (ga_grow(stack, 1) == FAIL) return FAIL; ! ((type_T **)stack->ga_data)[stack->ga_len] = &t_func_any; ! // TODO: argument and return types ++stack->ga_len; return OK; --- 1547,1559 ---- RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) return FAIL; ! isn->isn_arg.funcref.fr_func = ufunc->uf_dfunc_idx; isn->isn_arg.funcref.fr_var_idx = cctx->ctx_closure_count++; if (ga_grow(stack, 1) == FAIL) return FAIL; ! ((type_T **)stack->ga_data)[stack->ga_len] = ! ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type; ++stack->ga_len; return OK; *************** *** 1713,1719 **** } } if (ufunc->uf_def_status == UF_TO_BE_COMPILED) ! if (compile_def_function(ufunc, TRUE, NULL) == FAIL) return FAIL; } --- 1715,1722 ---- } } if (ufunc->uf_def_status == UF_TO_BE_COMPILED) ! if (compile_def_function(ufunc, ufunc->uf_ret_type == NULL, NULL) ! == FAIL) return FAIL; } *************** *** 3338,3344 **** clear_evalarg(&evalarg, NULL); if (ufunc->uf_def_status == UF_COMPILED) ! return generate_FUNCREF(cctx, ufunc->uf_dfunc_idx); func_ptr_unref(ufunc); return FAIL; --- 3341,3352 ---- clear_evalarg(&evalarg, NULL); if (ufunc->uf_def_status == UF_COMPILED) ! { ! // The return type will now be known. ! set_function_type(ufunc); ! ! return generate_FUNCREF(cctx, ufunc); ! } func_ptr_unref(ufunc); return FAIL; *************** *** 4982,4988 **** TRUE, ufunc->uf_func_type); if (lvar == NULL) return NULL; ! if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL) return NULL; r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); } --- 4990,4996 ---- TRUE, ufunc->uf_func_type); if (lvar == NULL) return NULL; ! if (generate_FUNCREF(cctx, ufunc) == FAIL) return NULL; r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); } *** ../vim-8.2.1395/src/testdir/test_vim9_func.vim 2020-08-08 15:10:23.863089456 +0200 --- src/testdir/test_vim9_func.vim 2020-08-08 16:39:07.112705395 +0200 *************** *** 503,518 **** enddef def Test_return_type_wrong() ! CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef', 'defcompile'], 'expected number but got string') ! CheckScriptFailure(['def Func(): string', 'return 1', 'enddef', 'defcompile'], 'expected string but got number') ! CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef', 'defcompile'], 'E1096: Returning a value in a function without a return type') ! CheckScriptFailure(['def Func()', 'return "a"', 'enddef', 'defcompile'], 'E1096: Returning a value in a function without a return type') ! CheckScriptFailure(['def Func(): number', 'return', 'enddef', 'defcompile'], 'E1003:') CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') enddef def Test_arg_type_wrong() --- 503,550 ---- enddef def Test_return_type_wrong() ! CheckScriptFailure([ ! 'def Func(): number', ! 'return "a"', ! 'enddef', ! 'defcompile'], 'expected number but got string') ! CheckScriptFailure([ ! 'def Func(): string', ! 'return 1', ! 'enddef', ! 'defcompile'], 'expected string but got number') ! CheckScriptFailure([ ! 'def Func(): void', ! 'return "a"', ! 'enddef', ! 'defcompile'], ! 'E1096: Returning a value in a function without a return type') ! CheckScriptFailure([ ! 'def Func()', ! 'return "a"', ! 'enddef', ! 'defcompile'], ! 'E1096: Returning a value in a function without a return type') ! CheckScriptFailure([ ! 'def Func(): number', ! 'return', ! 'enddef', ! 'defcompile'], 'E1003:') CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') + + CheckScriptFailure([ + 'vim9script', + 'def FuncB()', + ' return 123', + 'enddef', + 'def FuncA()', + ' FuncB()', + 'enddef', + 'defcompile'], 'E1096:') enddef def Test_arg_type_wrong() *** ../vim-8.2.1395/src/version.c 2020-08-08 15:45:58.233358630 +0200 --- src/version.c 2020-08-08 15:55:35.615202057 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1396, /**/ -- hundred-and-one symptoms of being an internet addict: 153. You find yourself staring at your "inbox" waiting for new e-mail to arrive. /// 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 ///