diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-06-12 15:58:16 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-06-12 15:58:16 +0200 |
commit | a9931535387e5eb4e6ce62f2a661484de4a1757d (patch) | |
tree | 4c6c45dab74c4c5bf3f27939d4ddb8a2282c77dd | |
parent | 742357718000927d652b1a98d313a3950571c8ec (diff) | |
download | vim-git-a9931535387e5eb4e6ce62f2a661484de4a1757d.tar.gz |
patch 8.2.2983: Vim9: an inline function requires specifying the return typev8.2.2983
Problem: Vim9: an inline function requires specifying the return type.
Solution: Make the return type optional.
-rw-r--r-- | src/eval.c | 8 | ||||
-rw-r--r-- | src/testdir/test_vim9_func.vim | 20 | ||||
-rw-r--r-- | src/userfunc.c | 2 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 15 |
5 files changed, 41 insertions, 6 deletions
diff --git a/src/eval.c b/src/eval.c index ca181d524..8a6539e3f 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3530,9 +3530,13 @@ eval7( { ufunc_T *ufunc = rettv->vval.v_partial->pt_func; - // compile it here to get the return type + // Compile it here to get the return type. The return + // type is optional, when it's missing use t_unknown. + // This is recognized in compile_return(). + if (ufunc->uf_ret_type->tt_type == VAR_VOID) + ufunc->uf_ret_type = &t_unknown; if (compile_def_function(ufunc, - TRUE, PROFILING(ufunc), NULL) == FAIL) + FALSE, PROFILING(ufunc), NULL) == FAIL) { clear_tv(rettv); ret = FAIL; diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 96e144f5d..925e7c82a 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -948,6 +948,26 @@ def Test_lambda_return_type() echo FilterWithCond('foo', (v) => v .. '^b') END CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1) + + lines =<< trim END + var Lambda1 = (x) => { + return x + } + assert_equal('asdf', Lambda1('asdf')) + var Lambda2 = (x): string => { + return x + } + assert_equal('foo', Lambda2('foo')) + END + CheckDefAndScriptSuccess(lines) + + lines =<< trim END + var Lambda = (x): string => { + return x + } + echo Lambda(['foo']) + END + CheckDefExecAndScriptFailure(lines, 'E1012:') enddef def Test_lambda_uses_assigned_var() diff --git a/src/userfunc.c b/src/userfunc.c index 64e815d04..f610c022d 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1377,7 +1377,7 @@ get_lambda_tv( goto errret; } else - fp->uf_ret_type = &t_any; + fp->uf_ret_type = &t_unknown; } fp->uf_lines = newlines; diff --git a/src/version.c b/src/version.c index 17ae9a4de..fcb0d927a 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2983, +/**/ 2982, /**/ 2981, diff --git a/src/vim9compile.c b/src/vim9compile.c index 44c082d41..dfd5aaa3c 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3565,8 +3565,12 @@ compile_lambda(char_u **arg, cctx_T *cctx) ++ufunc->uf_refcount; clear_tv(&rettv); - // Compile the function into instructions. - compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx); + // Compile it here to get the return type. The return type is optional, + // when it's missing use t_unknown. This is recognized in + // compile_return(). + if (ufunc->uf_ret_type->tt_type == VAR_VOID) + ufunc->uf_ret_type = &t_unknown; + compile_def_function(ufunc, FALSE, PROFILING(ufunc), cctx); // evalarg.eval_tofree_cmdline may have a copy of the last line and "*arg" // points into it. Point to the original line to avoid a dangling pointer. @@ -5398,10 +5402,15 @@ compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx) if (cctx->ctx_skip != SKIP_YES) { + // "check_return_type" with uf_ret_type set to &t_unknown is used + // for an inline function without a specified return type. Set the + // return type here. stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; - if (check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL + if ((check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL || cctx->ctx_ufunc->uf_ret_type == &t_unknown || cctx->ctx_ufunc->uf_ret_type == &t_any)) + || (!check_return_type + && cctx->ctx_ufunc->uf_ret_type == &t_unknown)) { cctx->ctx_ufunc->uf_ret_type = stack_type; } |