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?