Mercurial > vim
comparison src/vim9compile.c @ 21693:4e4fd845553d v8.2.1396
patch 8.2.1396: Vim9: no error for unexpectedly returning a value
Commit: https://github.com/vim/vim/commit/5a849da57c5fb54ffcffd436a9e00ef40fdf094c
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Aug 8 16:47:30 2020 +0200
patch 8.2.1396: Vim9: no error for unexpectedly returning a value
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.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 08 Aug 2020 17:00:04 +0200 |
parents | f41c646cb8b9 |
children | 1b96535705a0 |
comparison
equal
deleted
inserted
replaced
21692:c008e8068ad8 | 21693:4e4fd845553d |
---|---|
660 if (expected->tt_args != NULL && actual->tt_args != NULL) | 660 if (expected->tt_args != NULL && actual->tt_args != NULL) |
661 { | 661 { |
662 int i; | 662 int i; |
663 | 663 |
664 for (i = 0; i < expected->tt_argcount; ++i) | 664 for (i = 0; i < expected->tt_argcount; ++i) |
665 if (check_type(expected->tt_args[i], actual->tt_args[i], | 665 // Allow for using "any" argument type, lambda's have them. |
666 FALSE) == FAIL) | 666 if (actual->tt_args[i] != &t_any && check_type( |
667 expected->tt_args[i], actual->tt_args[i], FALSE) | |
668 == FAIL) | |
667 { | 669 { |
668 ret = FAIL; | 670 ret = FAIL; |
669 break; | 671 break; |
670 } | 672 } |
671 } | 673 } |
1535 | 1537 |
1536 /* | 1538 /* |
1537 * Generate an ISN_FUNCREF instruction. | 1539 * Generate an ISN_FUNCREF instruction. |
1538 */ | 1540 */ |
1539 static int | 1541 static int |
1540 generate_FUNCREF(cctx_T *cctx, int dfunc_idx) | 1542 generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc) |
1541 { | 1543 { |
1542 isn_T *isn; | 1544 isn_T *isn; |
1543 garray_T *stack = &cctx->ctx_type_stack; | 1545 garray_T *stack = &cctx->ctx_type_stack; |
1544 | 1546 |
1545 RETURN_OK_IF_SKIP(cctx); | 1547 RETURN_OK_IF_SKIP(cctx); |
1546 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) | 1548 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) |
1547 return FAIL; | 1549 return FAIL; |
1548 isn->isn_arg.funcref.fr_func = dfunc_idx; | 1550 isn->isn_arg.funcref.fr_func = ufunc->uf_dfunc_idx; |
1549 isn->isn_arg.funcref.fr_var_idx = cctx->ctx_closure_count++; | 1551 isn->isn_arg.funcref.fr_var_idx = cctx->ctx_closure_count++; |
1550 | 1552 |
1551 if (ga_grow(stack, 1) == FAIL) | 1553 if (ga_grow(stack, 1) == FAIL) |
1552 return FAIL; | 1554 return FAIL; |
1553 ((type_T **)stack->ga_data)[stack->ga_len] = &t_func_any; | 1555 ((type_T **)stack->ga_data)[stack->ga_len] = |
1554 // TODO: argument and return types | 1556 ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type; |
1555 ++stack->ga_len; | 1557 ++stack->ga_len; |
1556 | 1558 |
1557 return OK; | 1559 return OK; |
1558 } | 1560 } |
1559 | 1561 |
1711 arg_type_mismatch(expected, actual, i + 1); | 1713 arg_type_mismatch(expected, actual, i + 1); |
1712 return FAIL; | 1714 return FAIL; |
1713 } | 1715 } |
1714 } | 1716 } |
1715 if (ufunc->uf_def_status == UF_TO_BE_COMPILED) | 1717 if (ufunc->uf_def_status == UF_TO_BE_COMPILED) |
1716 if (compile_def_function(ufunc, TRUE, NULL) == FAIL) | 1718 if (compile_def_function(ufunc, ufunc->uf_ret_type == NULL, NULL) |
1719 == FAIL) | |
1717 return FAIL; | 1720 return FAIL; |
1718 } | 1721 } |
1719 | 1722 |
1720 if ((isn = generate_instr(cctx, | 1723 if ((isn = generate_instr(cctx, |
1721 ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL | 1724 ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL |
3336 compile_def_function(ufunc, TRUE, cctx); | 3339 compile_def_function(ufunc, TRUE, cctx); |
3337 | 3340 |
3338 clear_evalarg(&evalarg, NULL); | 3341 clear_evalarg(&evalarg, NULL); |
3339 | 3342 |
3340 if (ufunc->uf_def_status == UF_COMPILED) | 3343 if (ufunc->uf_def_status == UF_COMPILED) |
3341 return generate_FUNCREF(cctx, ufunc->uf_dfunc_idx); | 3344 { |
3345 // The return type will now be known. | |
3346 set_function_type(ufunc); | |
3347 | |
3348 return generate_FUNCREF(cctx, ufunc); | |
3349 } | |
3342 | 3350 |
3343 func_ptr_unref(ufunc); | 3351 func_ptr_unref(ufunc); |
3344 return FAIL; | 3352 return FAIL; |
3345 } | 3353 } |
3346 | 3354 |
4980 // Define a local variable for the function reference. | 4988 // Define a local variable for the function reference. |
4981 lvar = reserve_local(cctx, name_start, name_end - name_start, | 4989 lvar = reserve_local(cctx, name_start, name_end - name_start, |
4982 TRUE, ufunc->uf_func_type); | 4990 TRUE, ufunc->uf_func_type); |
4983 if (lvar == NULL) | 4991 if (lvar == NULL) |
4984 return NULL; | 4992 return NULL; |
4985 if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL) | 4993 if (generate_FUNCREF(cctx, ufunc) == FAIL) |
4986 return NULL; | 4994 return NULL; |
4987 r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); | 4995 r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); |
4988 } | 4996 } |
4989 | 4997 |
4990 // TODO: warning for trailing text? | 4998 // TODO: warning for trailing text? |