Mercurial > vim
comparison src/vim9compile.c @ 22284:6b385c2b9ff5 v8.2.1691
patch 8.2.1691: Vim9: list<any> is not accepted where list<number> is expected
Commit: https://github.com/vim/vim/commit/5e654230777ad21363a929dce3cfe0387da031a7
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Sep 16 15:22:00 2020 +0200
patch 8.2.1691: Vim9: list<any> is not accepted where list<number> is expected
Problem: Vim9: list<any> is not accepted where list<number> is expected.
Solution: Add functions to allocate and free a type_T, use it in
ISN_CHECKTYPE. (closes #6959)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 16 Sep 2020 15:30:07 +0200 |
parents | 753452747ae5 |
children | 3515f341e8ac |
comparison
equal
deleted
inserted
replaced
22283:84bd68382a9a | 22284:6b385c2b9ff5 |
---|---|
702 | 702 |
703 return OK; | 703 return OK; |
704 } | 704 } |
705 | 705 |
706 static int | 706 static int |
707 generate_TYPECHECK(cctx_T *cctx, type_T *vartype, int offset) | 707 generate_TYPECHECK( |
708 cctx_T *cctx, | |
709 type_T *expected, | |
710 int offset) | |
708 { | 711 { |
709 isn_T *isn; | 712 isn_T *isn; |
710 garray_T *stack = &cctx->ctx_type_stack; | 713 garray_T *stack = &cctx->ctx_type_stack; |
711 | 714 |
712 RETURN_OK_IF_SKIP(cctx); | 715 RETURN_OK_IF_SKIP(cctx); |
713 if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL) | 716 if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL) |
714 return FAIL; | 717 return FAIL; |
715 // TODO: whole type, e.g. for a function also arg and return types | 718 isn->isn_arg.type.ct_type = alloc_type(expected); |
716 isn->isn_arg.type.ct_type = vartype->tt_type; | |
717 isn->isn_arg.type.ct_off = offset; | 719 isn->isn_arg.type.ct_off = offset; |
718 | 720 |
719 // type becomes vartype | 721 // type becomes expected |
720 ((type_T **)stack->ga_data)[stack->ga_len + offset] = vartype; | 722 ((type_T **)stack->ga_data)[stack->ga_len + offset] = expected; |
721 | 723 |
722 return OK; | 724 return OK; |
723 } | 725 } |
724 | 726 |
725 /* | 727 /* |
726 * Check that | 728 * Check that |
727 * - "actual" is "expected" type or | 729 * - "actual" matches "expected" type or |
728 * - "actual" is a type that can be "expected" type: add a runtime check; or | 730 * - "actual" is a type that can be "expected" type: add a runtime check; or |
729 * - return FAIL. | 731 * - return FAIL. |
730 */ | 732 */ |
731 static int | 733 static int |
732 need_type( | 734 need_type( |
745 return OK; | 747 return OK; |
746 } | 748 } |
747 | 749 |
748 if (check_type(expected, actual, FALSE, 0) == OK) | 750 if (check_type(expected, actual, FALSE, 0) == OK) |
749 return OK; | 751 return OK; |
750 if (actual->tt_type != VAR_ANY | 752 |
751 && actual->tt_type != VAR_UNKNOWN | 753 // If the actual type can be the expected type add a runtime check. |
752 && !(actual->tt_type == VAR_FUNC | 754 // TODO: if it's a constant a runtime check makes no sense. |
753 && (actual->tt_member == &t_any || actual->tt_argcount < 0))) | 755 if (actual->tt_type == VAR_ANY |
754 { | 756 || actual->tt_type == VAR_UNKNOWN |
755 if (!silent) | 757 || (actual->tt_type == VAR_FUNC |
756 type_mismatch(expected, actual); | 758 && (expected->tt_type == VAR_FUNC |
757 return FAIL; | 759 || expected->tt_type == VAR_PARTIAL) |
758 } | 760 && (actual->tt_member == &t_any || actual->tt_argcount < 0)) |
759 generate_TYPECHECK(cctx, expected, offset); | 761 || (actual->tt_type == VAR_LIST |
760 return OK; | 762 && expected->tt_type == VAR_LIST |
763 && actual->tt_member == &t_any) | |
764 || (actual->tt_type == VAR_DICT | |
765 && expected->tt_type == VAR_DICT | |
766 && actual->tt_member == &t_any)) | |
767 { | |
768 generate_TYPECHECK(cctx, expected, offset); | |
769 return OK; | |
770 } | |
771 | |
772 if (!silent) | |
773 type_mismatch(expected, actual); | |
774 return FAIL; | |
761 } | 775 } |
762 | 776 |
763 /* | 777 /* |
764 * Generate an ISN_PUSHNR instruction. | 778 * Generate an ISN_PUSHNR instruction. |
765 */ | 779 */ |
774 return FAIL; | 788 return FAIL; |
775 isn->isn_arg.number = number; | 789 isn->isn_arg.number = number; |
776 | 790 |
777 if (number == 0 || number == 1) | 791 if (number == 0 || number == 1) |
778 { | 792 { |
779 type_T *type = alloc_type(cctx->ctx_type_list); | 793 type_T *type = get_type_ptr(cctx->ctx_type_list); |
780 | 794 |
781 // A 0 or 1 number can also be used as a bool. | 795 // A 0 or 1 number can also be used as a bool. |
782 if (type != NULL) | 796 if (type != NULL) |
783 { | 797 { |
784 type->tt_type = VAR_NUMBER; | 798 type->tt_type = VAR_NUMBER; |
4035 | 4049 |
4036 // The resulting type can be used as a bool. | 4050 // The resulting type can be used as a bool. |
4037 typep = ((type_T **)stack->ga_data) + stack->ga_len - 1; | 4051 typep = ((type_T **)stack->ga_data) + stack->ga_len - 1; |
4038 if (*typep != &t_bool) | 4052 if (*typep != &t_bool) |
4039 { | 4053 { |
4040 type_T *type = alloc_type(cctx->ctx_type_list); | 4054 type_T *type = get_type_ptr(cctx->ctx_type_list); |
4041 | 4055 |
4042 if (type != NULL) | 4056 if (type != NULL) |
4043 { | 4057 { |
4044 *type = **typep; | 4058 *type = **typep; |
4045 type->tt_flags |= TTFLAG_BOOL_OK; | 4059 type->tt_flags |= TTFLAG_BOOL_OK; |
7288 vim_free(lambda); | 7302 vim_free(lambda); |
7289 vim_free(isn->isn_arg.newfunc.nf_global); | 7303 vim_free(isn->isn_arg.newfunc.nf_global); |
7290 } | 7304 } |
7291 break; | 7305 break; |
7292 | 7306 |
7307 case ISN_CHECKTYPE: | |
7308 free_type(isn->isn_arg.type.ct_type); | |
7309 break; | |
7310 | |
7293 case ISN_2BOOL: | 7311 case ISN_2BOOL: |
7294 case ISN_2STRING: | 7312 case ISN_2STRING: |
7295 case ISN_2STRING_ANY: | 7313 case ISN_2STRING_ANY: |
7296 case ISN_ADDBLOB: | 7314 case ISN_ADDBLOB: |
7297 case ISN_ADDLIST: | 7315 case ISN_ADDLIST: |
7299 case ISN_ANYSLICE: | 7317 case ISN_ANYSLICE: |
7300 case ISN_BCALL: | 7318 case ISN_BCALL: |
7301 case ISN_CATCH: | 7319 case ISN_CATCH: |
7302 case ISN_CHECKLEN: | 7320 case ISN_CHECKLEN: |
7303 case ISN_CHECKNR: | 7321 case ISN_CHECKNR: |
7304 case ISN_CHECKTYPE: | |
7305 case ISN_COMPAREANY: | 7322 case ISN_COMPAREANY: |
7306 case ISN_COMPAREBLOB: | 7323 case ISN_COMPAREBLOB: |
7307 case ISN_COMPAREBOOL: | 7324 case ISN_COMPAREBOOL: |
7308 case ISN_COMPAREDICT: | 7325 case ISN_COMPAREDICT: |
7309 case ISN_COMPAREFLOAT: | 7326 case ISN_COMPAREFLOAT: |