Mercurial > vim
comparison src/vim9cmds.c @ 26935:ccb9be1cdd71 v8.2.3996
patch 8.2.3996: Vim9: type checking lacks information about declared type
Commit: https://github.com/vim/vim/commit/078a46161e8b1b30bf306d6c1f4f0af7c616a989
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 4 15:17:03 2022 +0000
patch 8.2.3996: Vim9: type checking lacks information about declared type
Problem: Vim9: type checking for list and dict lacks information about
declared type.
Solution: Add dv_decl_type and lv_decl_type. Refactor the type stack to
store two types in each entry.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 04 Jan 2022 16:30:06 +0100 |
parents | c2186e32ae42 |
children | 8dc4782b60ff |
comparison
equal
deleted
inserted
replaced
26934:2d3dd8065e25 | 26935:ccb9be1cdd71 |
---|---|
767 char_u *wp; | 767 char_u *wp; |
768 int var_count = 0; | 768 int var_count = 0; |
769 int var_list = FALSE; | 769 int var_list = FALSE; |
770 int semicolon = FALSE; | 770 int semicolon = FALSE; |
771 size_t varlen; | 771 size_t varlen; |
772 garray_T *stack = &cctx->ctx_type_stack; | |
773 garray_T *instr = &cctx->ctx_instr; | 772 garray_T *instr = &cctx->ctx_instr; |
774 scope_T *scope; | 773 scope_T *scope; |
775 lvar_T *loop_lvar; // loop iteration variable | 774 lvar_T *loop_lvar; // loop iteration variable |
776 lvar_T *var_lvar; // variable for "var" | 775 lvar_T *var_lvar; // variable for "var" |
777 type_T *vartype; | 776 type_T *vartype; |
839 | 838 |
840 if (cctx->ctx_skip != SKIP_YES) | 839 if (cctx->ctx_skip != SKIP_YES) |
841 { | 840 { |
842 // If we know the type of "var" and it is not a supported type we can | 841 // If we know the type of "var" and it is not a supported type we can |
843 // give an error now. | 842 // give an error now. |
844 vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 843 vartype = get_type_on_stack(cctx, 0); |
845 if (vartype->tt_type != VAR_LIST | 844 if (vartype->tt_type != VAR_LIST |
846 && vartype->tt_type != VAR_STRING | 845 && vartype->tt_type != VAR_STRING |
847 && vartype->tt_type != VAR_BLOB | 846 && vartype->tt_type != VAR_BLOB |
848 && vartype->tt_type != VAR_ANY | 847 && vartype->tt_type != VAR_ANY |
849 && vartype->tt_type != VAR_UNKNOWN) | 848 && vartype->tt_type != VAR_UNKNOWN) |
896 if (var_list) | 895 if (var_list) |
897 { | 896 { |
898 generate_UNPACK(cctx, var_count, semicolon); | 897 generate_UNPACK(cctx, var_count, semicolon); |
899 arg = skipwhite(arg + 1); // skip white after '[' | 898 arg = skipwhite(arg + 1); // skip white after '[' |
900 | 899 |
901 // the list item is replaced by a number of items | 900 // drop the list item |
902 if (GA_GROW_FAILS(stack, var_count - 1)) | 901 --cctx->ctx_type_stack.ga_len; |
903 { | 902 |
904 drop_scope(cctx); | 903 // add type of the items |
905 return NULL; | |
906 } | |
907 --stack->ga_len; | |
908 for (idx = 0; idx < var_count; ++idx) | 904 for (idx = 0; idx < var_count; ++idx) |
909 { | 905 { |
910 ((type_T **)stack->ga_data)[stack->ga_len] = | 906 type_T *type = (semicolon && idx == 0) ? vartype : item_type; |
911 (semicolon && idx == 0) ? vartype : item_type; | 907 |
912 ++stack->ga_len; | 908 if (push_type_stack(cctx, type) == FAIL) |
909 { | |
910 drop_scope(cctx); | |
911 return NULL; | |
912 } | |
913 } | 913 } |
914 } | 914 } |
915 | 915 |
916 for (idx = 0; idx < var_count; ++idx) | 916 for (idx = 0; idx < var_count; ++idx) |
917 { | 917 { |
1645 char_u *p = arg; | 1645 char_u *p = arg; |
1646 char_u *prev = arg; | 1646 char_u *prev = arg; |
1647 char_u *expr_start; | 1647 char_u *expr_start; |
1648 int count = 0; | 1648 int count = 0; |
1649 int start_ctx_lnum = cctx->ctx_lnum; | 1649 int start_ctx_lnum = cctx->ctx_lnum; |
1650 garray_T *stack = &cctx->ctx_type_stack; | |
1651 type_T *type; | 1650 type_T *type; |
1652 | 1651 |
1653 for (;;) | 1652 for (;;) |
1654 { | 1653 { |
1655 if (ends_excmd2(prev, p)) | 1654 if (ends_excmd2(prev, p)) |
1659 return NULL; | 1658 return NULL; |
1660 | 1659 |
1661 if (cctx->ctx_skip != SKIP_YES) | 1660 if (cctx->ctx_skip != SKIP_YES) |
1662 { | 1661 { |
1663 // check for non-void type | 1662 // check for non-void type |
1664 type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 1663 type = get_type_on_stack(cctx, 0); |
1665 if (type->tt_type == VAR_VOID) | 1664 if (type->tt_type == VAR_VOID) |
1666 { | 1665 { |
1667 semsg(_(e_expression_does_not_result_in_value_str), expr_start); | 1666 semsg(_(e_expression_does_not_result_in_value_str), expr_start); |
1668 return NULL; | 1667 return NULL; |
1669 } | 1668 } |
2180 */ | 2179 */ |
2181 char_u * | 2180 char_u * |
2182 compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx) | 2181 compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx) |
2183 { | 2182 { |
2184 char_u *p = arg; | 2183 char_u *p = arg; |
2185 garray_T *stack = &cctx->ctx_type_stack; | |
2186 type_T *stack_type; | 2184 type_T *stack_type; |
2187 | 2185 |
2188 if (*p != NUL && *p != '|' && *p != '\n') | 2186 if (*p != NUL && *p != '|' && *p != '\n') |
2189 { | 2187 { |
2190 if (legacy) | 2188 if (legacy) |
2209 if (cctx->ctx_skip != SKIP_YES) | 2207 if (cctx->ctx_skip != SKIP_YES) |
2210 { | 2208 { |
2211 // "check_return_type" with uf_ret_type set to &t_unknown is used | 2209 // "check_return_type" with uf_ret_type set to &t_unknown is used |
2212 // for an inline function without a specified return type. Set the | 2210 // for an inline function without a specified return type. Set the |
2213 // return type here. | 2211 // return type here. |
2214 stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 2212 stack_type = get_type_on_stack(cctx, 0); |
2215 if ((check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL | 2213 if ((check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL |
2216 || cctx->ctx_ufunc->uf_ret_type == &t_unknown | 2214 || cctx->ctx_ufunc->uf_ret_type == &t_unknown |
2217 || cctx->ctx_ufunc->uf_ret_type == &t_any)) | 2215 || cctx->ctx_ufunc->uf_ret_type == &t_any)) |
2218 || (!check_return_type | 2216 || (!check_return_type |
2219 && cctx->ctx_ufunc->uf_ret_type == &t_unknown)) | 2217 && cctx->ctx_ufunc->uf_ret_type == &t_unknown)) |