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: