comparison src/vim9compile.c @ 22631:59cd5f8b2ab2 v8.2.1864

patch 8.2.1864: Vim9: no error for wrong list type Commit: https://github.com/vim/vim/commit/334a8b4bde55e1095533f70616ac1e6ec337c62c Author: Bram Moolenaar <Bram@vim.org> Date: Mon Oct 19 16:07:42 2020 +0200 patch 8.2.1864: Vim9: no error for wrong list type Problem: Vim9: no error for wrong list type. Solution: Add flag to indicate a constant. (closes https://github.com/vim/vim/issues/7160)
author Bram Moolenaar <Bram@vim.org>
date Mon, 19 Oct 2020 16:15:04 +0200
parents 1064b9f05b0a
children 6589dae9696c
comparison
equal deleted inserted replaced
22630:b484b36ca2ef 22631:59cd5f8b2ab2
813 813
814 return OK; 814 return OK;
815 } 815 }
816 816
817 /* 817 /*
818 * Return TRUE if "actual" could be "expected" and a runtime typecheck is to be
819 * used. Return FALSE if the types will never match.
820 */
821 static int
822 use_typecheck(type_T *actual, type_T *expected)
823 {
824 if (actual->tt_type == VAR_ANY
825 || actual->tt_type == VAR_UNKNOWN
826 || (actual->tt_type == VAR_FUNC
827 && (expected->tt_type == VAR_FUNC
828 || expected->tt_type == VAR_PARTIAL)
829 && (actual->tt_member == &t_any || actual->tt_argcount < 0)))
830 return TRUE;
831 if ((actual->tt_type == VAR_LIST || actual->tt_type == VAR_DICT)
832 && actual->tt_type == expected->tt_type)
833 // This takes care of a nested list or dict.
834 return use_typecheck(actual->tt_member, expected->tt_member);
835 return FALSE;
836 }
837
838 /*
818 * Check that 839 * Check that
819 * - "actual" matches "expected" type or 840 * - "actual" matches "expected" type or
820 * - "actual" is a type that can be "expected" type: add a runtime check; or 841 * - "actual" is a type that can be "expected" type: add a runtime check; or
821 * - return FAIL. 842 * - return FAIL.
843 * If "actual_is_const" is TRUE then the type won't change at runtime, do not
844 * generate a TYPECHECK.
822 */ 845 */
823 static int 846 static int
824 need_type( 847 need_type(
825 type_T *actual, 848 type_T *actual,
826 type_T *expected, 849 type_T *expected,
827 int offset, 850 int offset,
828 cctx_T *cctx, 851 cctx_T *cctx,
829 int silent) 852 int silent,
853 int actual_is_const)
830 { 854 {
831 if (expected == &t_bool && actual != &t_bool 855 if (expected == &t_bool && actual != &t_bool
832 && (actual->tt_flags & TTFLAG_BOOL_OK)) 856 && (actual->tt_flags & TTFLAG_BOOL_OK))
833 { 857 {
834 // Using "0", "1" or the result of an expression with "&&" or "||" as a 858 // Using "0", "1" or the result of an expression with "&&" or "||" as a
839 863
840 if (check_type(expected, actual, FALSE, 0) == OK) 864 if (check_type(expected, actual, FALSE, 0) == OK)
841 return OK; 865 return OK;
842 866
843 // If the actual type can be the expected type add a runtime check. 867 // If the actual type can be the expected type add a runtime check.
844 // TODO: if it's a constant a runtime check makes no sense. 868 // If it's a constant a runtime check makes no sense.
845 if (actual->tt_type == VAR_ANY 869 if (!actual_is_const && use_typecheck(actual, expected))
846 || actual->tt_type == VAR_UNKNOWN
847 || (actual->tt_type == VAR_FUNC
848 && (expected->tt_type == VAR_FUNC
849 || expected->tt_type == VAR_PARTIAL)
850 && (actual->tt_member == &t_any || actual->tt_argcount < 0))
851 || (actual->tt_type == VAR_LIST
852 && expected->tt_type == VAR_LIST
853 && actual->tt_member == &t_any)
854 || (actual->tt_type == VAR_DICT
855 && expected->tt_type == VAR_DICT
856 && actual->tt_member == &t_any))
857 { 870 {
858 generate_TYPECHECK(cctx, expected, offset); 871 generate_TYPECHECK(cctx, expected, offset);
859 return OK; 872 return OK;
860 } 873 }
861 874
1524 // possibly a lambda or "...: any" 1537 // possibly a lambda or "...: any"
1525 expected = &t_any; 1538 expected = &t_any;
1526 else 1539 else
1527 expected = ufunc->uf_va_type->tt_member; 1540 expected = ufunc->uf_va_type->tt_member;
1528 actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; 1541 actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
1529 if (need_type(actual, expected, -argcount + i, cctx, TRUE) == FAIL) 1542 if (need_type(actual, expected, -argcount + i, cctx,
1543 TRUE, FALSE) == FAIL)
1530 { 1544 {
1531 arg_type_mismatch(expected, actual, i + 1); 1545 arg_type_mismatch(expected, actual, i + 1);
1532 return FAIL; 1546 return FAIL;
1533 } 1547 }
1534 } 1548 }
2059 // Using 50 should be more than enough of 5 levels of (). 2073 // Using 50 should be more than enough of 5 levels of ().
2060 #define PPSIZE 50 2074 #define PPSIZE 50
2061 typedef struct { 2075 typedef struct {
2062 typval_T pp_tv[PPSIZE]; // stack of ppconst constants 2076 typval_T pp_tv[PPSIZE]; // stack of ppconst constants
2063 int pp_used; // active entries in pp_tv[] 2077 int pp_used; // active entries in pp_tv[]
2078 int pp_is_const; // all generated code was constants, used for a
2079 // list or dict with constant members
2064 } ppconst_T; 2080 } ppconst_T;
2065 2081
2082 static int compile_expr0_ext(char_u **arg, cctx_T *cctx, int *is_const);
2066 static int compile_expr0(char_u **arg, cctx_T *cctx); 2083 static int compile_expr0(char_u **arg, cctx_T *cctx);
2067 static int compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst); 2084 static int compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst);
2068 2085
2069 /* 2086 /*
2070 * Generate a PUSH instruction for "tv". 2087 * Generate a PUSH instruction for "tv".
2627 } 2644 }
2628 2645
2629 /* 2646 /*
2630 * parse a list: [expr, expr] 2647 * parse a list: [expr, expr]
2631 * "*arg" points to the '['. 2648 * "*arg" points to the '['.
2632 */ 2649 * ppconst->pp_is_const is set if all items are a constant.
2633 static int 2650 */
2634 compile_list(char_u **arg, cctx_T *cctx) 2651 static int
2652 compile_list(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2635 { 2653 {
2636 char_u *p = skipwhite(*arg + 1); 2654 char_u *p = skipwhite(*arg + 1);
2637 char_u *whitep = *arg + 1; 2655 char_u *whitep = *arg + 1;
2638 int count = 0; 2656 int count = 0;
2657 int is_const;
2658 int is_all_const = TRUE; // reset when non-const encountered
2639 2659
2640 for (;;) 2660 for (;;)
2641 { 2661 {
2642 if (may_get_next_line(whitep, &p, cctx) == FAIL) 2662 if (may_get_next_line(whitep, &p, cctx) == FAIL)
2643 { 2663 {
2652 if (*p == ']') 2672 if (*p == ']')
2653 { 2673 {
2654 ++p; 2674 ++p;
2655 break; 2675 break;
2656 } 2676 }
2657 if (compile_expr0(&p, cctx) == FAIL) 2677 if (compile_expr0_ext(&p, cctx, &is_const) == FAIL)
2658 return FAIL; 2678 return FAIL;
2679 if (!is_const)
2680 is_all_const = FALSE;
2659 ++count; 2681 ++count;
2660 if (*p == ',') 2682 if (*p == ',')
2661 { 2683 {
2662 ++p; 2684 ++p;
2663 if (*p != ']' && !IS_WHITE_OR_NUL(*p)) 2685 if (*p != ']' && !IS_WHITE_OR_NUL(*p))
2669 whitep = p; 2691 whitep = p;
2670 p = skipwhite(p); 2692 p = skipwhite(p);
2671 } 2693 }
2672 *arg = p; 2694 *arg = p;
2673 2695
2674 generate_NEWLIST(cctx, count); 2696 ppconst->pp_is_const = is_all_const;
2675 return OK; 2697 return generate_NEWLIST(cctx, count);
2676 } 2698 }
2677 2699
2678 /* 2700 /*
2679 * parse a lambda: {arg, arg -> expr} 2701 * parse a lambda: {arg, arg -> expr}
2680 * "*arg" points to the '{'. 2702 * "*arg" points to the '{'.
2770 } 2792 }
2771 2793
2772 /* 2794 /*
2773 * parse a dict: {'key': val} or #{key: val} 2795 * parse a dict: {'key': val} or #{key: val}
2774 * "*arg" points to the '{'. 2796 * "*arg" points to the '{'.
2775 */ 2797 * ppconst->pp_is_const is set if all item values are a constant.
2776 static int 2798 */
2777 compile_dict(char_u **arg, cctx_T *cctx, int literal) 2799 static int
2800 compile_dict(char_u **arg, cctx_T *cctx, int literal, ppconst_T *ppconst)
2778 { 2801 {
2779 garray_T *instr = &cctx->ctx_instr; 2802 garray_T *instr = &cctx->ctx_instr;
2780 garray_T *stack = &cctx->ctx_type_stack; 2803 garray_T *stack = &cctx->ctx_type_stack;
2781 int count = 0; 2804 int count = 0;
2782 dict_T *d = dict_alloc(); 2805 dict_T *d = dict_alloc();
2783 dictitem_T *item; 2806 dictitem_T *item;
2784 char_u *whitep = *arg; 2807 char_u *whitep = *arg;
2785 char_u *p; 2808 char_u *p;
2809 int is_const;
2810 int is_all_const = TRUE; // reset when non-const encountered
2786 2811
2787 if (d == NULL) 2812 if (d == NULL)
2788 return FAIL; 2813 return FAIL;
2789 *arg = skipwhite(*arg + 1); 2814 *arg = skipwhite(*arg + 1);
2790 for (;;) 2815 for (;;)
2825 key = isn->isn_arg.string; 2850 key = isn->isn_arg.string;
2826 else 2851 else
2827 { 2852 {
2828 type_T *keytype = ((type_T **)stack->ga_data) 2853 type_T *keytype = ((type_T **)stack->ga_data)
2829 [stack->ga_len - 1]; 2854 [stack->ga_len - 1];
2830 if (need_type(keytype, &t_string, -1, cctx, FALSE) == FAIL) 2855 if (need_type(keytype, &t_string, -1, cctx,
2856 FALSE, FALSE) == FAIL)
2831 return FAIL; 2857 return FAIL;
2832 } 2858 }
2833 } 2859 }
2834 2860
2835 // Check for duplicate keys, if using string keys. 2861 // Check for duplicate keys, if using string keys.
2871 { 2897 {
2872 *arg = NULL; 2898 *arg = NULL;
2873 goto failret; 2899 goto failret;
2874 } 2900 }
2875 2901
2876 if (compile_expr0(arg, cctx) == FAIL) 2902 if (compile_expr0_ext(arg, cctx, &is_const) == FAIL)
2877 return FAIL; 2903 return FAIL;
2904 if (!is_const)
2905 is_all_const = FALSE;
2878 ++count; 2906 ++count;
2879 2907
2880 whitep = *arg; 2908 whitep = *arg;
2881 *arg = skipwhite(*arg); 2909 *arg = skipwhite(*arg);
2882 if (may_get_next_line(whitep, arg, cctx) == FAIL) 2910 if (may_get_next_line(whitep, arg, cctx) == FAIL)
2906 p = skipwhite(*arg); 2934 p = skipwhite(*arg);
2907 if (VIM_ISWHITE(**arg) && vim9_comment_start(p)) 2935 if (VIM_ISWHITE(**arg) && vim9_comment_start(p))
2908 *arg += STRLEN(*arg); 2936 *arg += STRLEN(*arg);
2909 2937
2910 dict_unref(d); 2938 dict_unref(d);
2939 ppconst->pp_is_const = is_all_const;
2911 return generate_NEWDICT(cctx, count); 2940 return generate_NEWDICT(cctx, count);
2912 2941
2913 failret: 2942 failret:
2914 if (*arg == NULL) 2943 if (*arg == NULL)
2915 { 2944 {
3243 type_T *type; 3272 type_T *type;
3244 int argcount = 0; 3273 int argcount = 0;
3245 3274
3246 if (generate_ppconst(cctx, ppconst) == FAIL) 3275 if (generate_ppconst(cctx, ppconst) == FAIL)
3247 return FAIL; 3276 return FAIL;
3277 ppconst->pp_is_const = FALSE;
3248 3278
3249 // funcref(arg) 3279 // funcref(arg)
3250 type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 3280 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3251 3281
3252 *arg = skipwhite(p + 1); 3282 *arg = skipwhite(p + 1);
3259 { 3289 {
3260 char_u *pstart = p; 3290 char_u *pstart = p;
3261 3291
3262 if (generate_ppconst(cctx, ppconst) == FAIL) 3292 if (generate_ppconst(cctx, ppconst) == FAIL)
3263 return FAIL; 3293 return FAIL;
3294 ppconst->pp_is_const = FALSE;
3264 3295
3265 // something->method() 3296 // something->method()
3266 // Apply the '!', '-' and '+' first: 3297 // Apply the '!', '-' and '+' first:
3267 // -1.0->func() works like (-1.0)->func() 3298 // -1.0->func() works like (-1.0)->func()
3268 if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL) 3299 if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL)
3314 // TODO: blob index 3345 // TODO: blob index
3315 // TODO: more arguments 3346 // TODO: more arguments
3316 // TODO: recognize list or dict at runtime 3347 // TODO: recognize list or dict at runtime
3317 if (generate_ppconst(cctx, ppconst) == FAIL) 3348 if (generate_ppconst(cctx, ppconst) == FAIL)
3318 return FAIL; 3349 return FAIL;
3350 ppconst->pp_is_const = FALSE;
3319 3351
3320 ++p; 3352 ++p;
3321 *arg = skipwhite(p); 3353 *arg = skipwhite(p);
3322 if (may_get_next_line_error(p, arg, cctx) == FAIL) 3354 if (may_get_next_line_error(p, arg, cctx) == FAIL)
3323 return FAIL; 3355 return FAIL;
3369 // If the index is a string, the variable must be a Dict. 3401 // If the index is a string, the variable must be a Dict.
3370 if (*typep == &t_any && valtype == &t_string) 3402 if (*typep == &t_any && valtype == &t_string)
3371 vtype = VAR_DICT; 3403 vtype = VAR_DICT;
3372 if (vtype == VAR_STRING || vtype == VAR_LIST || vtype == VAR_BLOB) 3404 if (vtype == VAR_STRING || vtype == VAR_LIST || vtype == VAR_BLOB)
3373 { 3405 {
3374 if (need_type(valtype, &t_number, -1, cctx, FALSE) == FAIL) 3406 if (need_type(valtype, &t_number, -1, cctx,
3407 FALSE, FALSE) == FAIL)
3375 return FAIL; 3408 return FAIL;
3376 if (is_slice) 3409 if (is_slice)
3377 { 3410 {
3378 valtype = ((type_T **)stack->ga_data)[stack->ga_len - 2]; 3411 valtype = ((type_T **)stack->ga_data)[stack->ga_len - 2];
3379 if (need_type(valtype, &t_number, -2, cctx, FALSE) == FAIL) 3412 if (need_type(valtype, &t_number, -2, cctx,
3413 FALSE, FALSE) == FAIL)
3380 return FAIL; 3414 return FAIL;
3381 } 3415 }
3382 } 3416 }
3383 3417
3384 if (vtype == VAR_DICT) 3418 if (vtype == VAR_DICT)
3390 } 3424 }
3391 if ((*typep)->tt_type == VAR_DICT) 3425 if ((*typep)->tt_type == VAR_DICT)
3392 *typep = (*typep)->tt_member; 3426 *typep = (*typep)->tt_member;
3393 else 3427 else
3394 { 3428 {
3395 if (need_type(*typep, &t_dict_any, -2, cctx, FALSE) == FAIL) 3429 if (need_type(*typep, &t_dict_any, -2, cctx,
3430 FALSE, FALSE) == FAIL)
3396 return FAIL; 3431 return FAIL;
3397 *typep = &t_any; 3432 *typep = &t_any;
3398 } 3433 }
3399 if (may_generate_2STRING(-1, cctx) == FAIL) 3434 if (may_generate_2STRING(-1, cctx) == FAIL)
3400 return FAIL; 3435 return FAIL;
3439 return FAIL; 3474 return FAIL;
3440 } 3475 }
3441 } 3476 }
3442 else if (*p == '.' && p[1] != '.') 3477 else if (*p == '.' && p[1] != '.')
3443 { 3478 {
3479 // dictionary member: dict.name
3444 if (generate_ppconst(cctx, ppconst) == FAIL) 3480 if (generate_ppconst(cctx, ppconst) == FAIL)
3445 return FAIL; 3481 return FAIL;
3482 ppconst->pp_is_const = FALSE;
3446 3483
3447 *arg = p + 1; 3484 *arg = p + 1;
3448 if (may_get_next_line(*arg, arg, cctx) == FAIL) 3485 if (may_get_next_line(*arg, arg, cctx) == FAIL)
3449 { 3486 {
3450 emsg(_(e_missing_name_after_dot)); 3487 emsg(_(e_missing_name_after_dot));
3451 return FAIL; 3488 return FAIL;
3452 } 3489 }
3453 // dictionary member: dict.name
3454 p = *arg; 3490 p = *arg;
3455 if (eval_isdictc(*p)) 3491 if (eval_isdictc(*p))
3456 while (eval_isnamec(*p)) 3492 while (eval_isnamec(*p))
3457 MB_PTR_ADV(p); 3493 MB_PTR_ADV(p);
3458 if (p == *arg) 3494 if (p == *arg)
3478 3514
3479 /* 3515 /*
3480 * Compile an expression at "*arg" and add instructions to "cctx->ctx_instr". 3516 * Compile an expression at "*arg" and add instructions to "cctx->ctx_instr".
3481 * "arg" is advanced until after the expression, skipping white space. 3517 * "arg" is advanced until after the expression, skipping white space.
3482 * 3518 *
3483 * If the value is a constant "ppconst->pp_ret" will be set. 3519 * If the value is a constant "ppconst->pp_used" will be non-zero.
3484 * Before instructions are generated, any values in "ppconst" will generated. 3520 * Before instructions are generated, any values in "ppconst" will generated.
3485 * 3521 *
3486 * This is the compiling equivalent of eval1(), eval2(), etc. 3522 * This is the compiling equivalent of eval1(), eval2(), etc.
3487 */ 3523 */
3488 3524
3518 { 3554 {
3519 char_u *start_leader, *end_leader; 3555 char_u *start_leader, *end_leader;
3520 int ret = OK; 3556 int ret = OK;
3521 typval_T *rettv = &ppconst->pp_tv[ppconst->pp_used]; 3557 typval_T *rettv = &ppconst->pp_tv[ppconst->pp_used];
3522 int used_before = ppconst->pp_used; 3558 int used_before = ppconst->pp_used;
3559
3560 ppconst->pp_is_const = FALSE;
3523 3561
3524 /* 3562 /*
3525 * Skip '!', '-' and '+' characters. They are handled later. 3563 * Skip '!', '-' and '+' characters. They are handled later.
3526 */ 3564 */
3527 start_leader = *arg; 3565 start_leader = *arg;
3608 break; 3646 break;
3609 3647
3610 /* 3648 /*
3611 * List: [expr, expr] 3649 * List: [expr, expr]
3612 */ 3650 */
3613 case '[': ret = compile_list(arg, cctx); 3651 case '[': ret = compile_list(arg, cctx, ppconst);
3614 break; 3652 break;
3615 3653
3616 /* 3654 /*
3617 * Dictionary: #{key: val, key: val} 3655 * Dictionary: #{key: val, key: val}
3618 */ 3656 */
3619 case '#': if ((*arg)[1] == '{') 3657 case '#': if ((*arg)[1] == '{')
3620 { 3658 {
3621 ++*arg; 3659 ++*arg;
3622 ret = compile_dict(arg, cctx, TRUE); 3660 ret = compile_dict(arg, cctx, TRUE, ppconst);
3623 } 3661 }
3624 else 3662 else
3625 ret = NOTDONE; 3663 ret = NOTDONE;
3626 break; 3664 break;
3627 3665
3636 ret = get_function_args(&start, '-', NULL, 3674 ret = get_function_args(&start, '-', NULL,
3637 NULL, NULL, NULL, TRUE, NULL, NULL); 3675 NULL, NULL, NULL, TRUE, NULL, NULL);
3638 if (ret != FAIL && *start == '>') 3676 if (ret != FAIL && *start == '>')
3639 ret = compile_lambda(arg, cctx); 3677 ret = compile_lambda(arg, cctx);
3640 else 3678 else
3641 ret = compile_dict(arg, cctx, FALSE); 3679 ret = compile_dict(arg, cctx, FALSE, ppconst);
3642 } 3680 }
3643 break; 3681 break;
3644 3682
3645 /* 3683 /*
3646 * Option value: &name 3684 * Option value: &name
3805 3843
3806 generate_ppconst(cctx, ppconst); 3844 generate_ppconst(cctx, ppconst);
3807 actual = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 3845 actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3808 if (check_type(want_type, actual, FALSE, 0) == FAIL) 3846 if (check_type(want_type, actual, FALSE, 0) == FAIL)
3809 { 3847 {
3810 if (need_type(actual, want_type, -1, cctx, FALSE) == FAIL) 3848 if (need_type(actual, want_type, -1, cctx, FALSE, FALSE) == FAIL)
3811 return FAIL; 3849 return FAIL;
3812 } 3850 }
3813 } 3851 }
3814 3852
3815 return OK; 3853 return OK;
4418 return OK; 4456 return OK;
4419 } 4457 }
4420 4458
4421 /* 4459 /*
4422 * Toplevel expression. 4460 * Toplevel expression.
4423 */ 4461 * Sets "is_const" (if not NULL) to indicate the value is a constant.
4424 static int 4462 * Returns OK or FAIL.
4425 compile_expr0(char_u **arg, cctx_T *cctx) 4463 */
4464 static int
4465 compile_expr0_ext(char_u **arg, cctx_T *cctx, int *is_const)
4426 { 4466 {
4427 ppconst_T ppconst; 4467 ppconst_T ppconst;
4428 4468
4429 CLEAR_FIELD(ppconst); 4469 CLEAR_FIELD(ppconst);
4430 if (compile_expr1(arg, cctx, &ppconst) == FAIL) 4470 if (compile_expr1(arg, cctx, &ppconst) == FAIL)
4431 { 4471 {
4432 clear_ppconst(&ppconst); 4472 clear_ppconst(&ppconst);
4433 return FAIL; 4473 return FAIL;
4434 } 4474 }
4475 if (is_const != NULL)
4476 *is_const = ppconst.pp_used > 0 || ppconst.pp_is_const;
4435 if (generate_ppconst(cctx, &ppconst) == FAIL) 4477 if (generate_ppconst(cctx, &ppconst) == FAIL)
4436 return FAIL; 4478 return FAIL;
4437 return OK; 4479 return OK;
4480 }
4481
4482 /*
4483 * Toplevel expression.
4484 */
4485 static int
4486 compile_expr0(char_u **arg, cctx_T *cctx)
4487 {
4488 return compile_expr0_ext(arg, cctx, NULL);
4438 } 4489 }
4439 4490
4440 /* 4491 /*
4441 * compile "return [expr]" 4492 * compile "return [expr]"
4442 */ 4493 */
4464 { 4515 {
4465 emsg(_(e_returning_value_in_function_without_return_type)); 4516 emsg(_(e_returning_value_in_function_without_return_type));
4466 return NULL; 4517 return NULL;
4467 } 4518 }
4468 if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, 4519 if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1,
4469 cctx, FALSE) == FAIL) 4520 cctx, FALSE, FALSE) == FAIL)
4470 return NULL; 4521 return NULL;
4471 } 4522 }
4472 } 4523 }
4473 else 4524 else
4474 { 4525 {
4832 if (stacktype->tt_type == VAR_VOID) 4883 if (stacktype->tt_type == VAR_VOID)
4833 { 4884 {
4834 emsg(_(e_cannot_use_void_value)); 4885 emsg(_(e_cannot_use_void_value));
4835 goto theend; 4886 goto theend;
4836 } 4887 }
4837 if (need_type(stacktype, &t_list_any, -1, cctx, FALSE) == FAIL) 4888 if (need_type(stacktype, &t_list_any, -1, cctx,
4889 FALSE, FALSE) == FAIL)
4838 goto theend; 4890 goto theend;
4839 // TODO: check the length of a constant list here 4891 // TODO: check the length of a constant list here
4840 generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count, 4892 generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count,
4841 semicolon); 4893 semicolon);
4842 } 4894 }
5192 } 5244 }
5193 } 5245 }
5194 else if (oplen > 0) 5246 else if (oplen > 0)
5195 { 5247 {
5196 type_T *stacktype; 5248 type_T *stacktype;
5249 int is_const = FALSE;
5197 5250
5198 // For "var = expr" evaluate the expression. 5251 // For "var = expr" evaluate the expression.
5199 if (var_count == 0) 5252 if (var_count == 0)
5200 { 5253 {
5201 int r; 5254 int r;
5217 // variable here, it is not available to this expression. 5270 // variable here, it is not available to this expression.
5218 if (new_local) 5271 if (new_local)
5219 --cctx->ctx_locals.ga_len; 5272 --cctx->ctx_locals.ga_len;
5220 instr_count = instr->ga_len; 5273 instr_count = instr->ga_len;
5221 p = skipwhite(op + oplen); 5274 p = skipwhite(op + oplen);
5222 r = compile_expr0(&p, cctx); 5275 r = compile_expr0_ext(&p, cctx, &is_const);
5223 if (new_local) 5276 if (new_local)
5224 ++cctx->ctx_locals.ga_len; 5277 ++cctx->ctx_locals.ga_len;
5225 if (r == FAIL) 5278 if (r == FAIL)
5226 goto theend; 5279 goto theend;
5227 } 5280 }
5279 use_type = use_type->tt_member; 5332 use_type = use_type->tt_member;
5280 if (use_type == NULL) 5333 if (use_type == NULL)
5281 // could be indexing "any" 5334 // could be indexing "any"
5282 use_type = &t_any; 5335 use_type = &t_any;
5283 } 5336 }
5284 if (need_type(stacktype, use_type, -1, cctx, FALSE) 5337 if (need_type(stacktype, use_type, -1, cctx,
5285 == FAIL) 5338 FALSE, is_const) == FAIL)
5286 goto theend; 5339 goto theend;
5287 } 5340 }
5288 } 5341 }
5289 else if (*p != '=' && need_type(stacktype, member_type, -1, 5342 else if (*p != '=' && need_type(stacktype, member_type, -1,
5290 cctx, FALSE) == FAIL) 5343 cctx, FALSE, FALSE) == FAIL)
5291 goto theend; 5344 goto theend;
5292 } 5345 }
5293 else if (cmdidx == CMD_final) 5346 else if (cmdidx == CMD_final)
5294 { 5347 {
5295 emsg(_(e_final_requires_a_value)); 5348 emsg(_(e_final_requires_a_value));
5372 if ( 5425 if (
5373 #ifdef FEAT_FLOAT 5426 #ifdef FEAT_FLOAT
5374 // If variable is float operation with number is OK. 5427 // If variable is float operation with number is OK.
5375 !(expected == &t_float && stacktype == &t_number) && 5428 !(expected == &t_float && stacktype == &t_number) &&
5376 #endif 5429 #endif
5377 need_type(stacktype, expected, -1, cctx, FALSE) == FAIL) 5430 need_type(stacktype, expected, -1, cctx,
5431 FALSE, FALSE) == FAIL)
5378 goto theend; 5432 goto theend;
5379 5433
5380 if (*op == '.') 5434 if (*op == '.')
5381 { 5435 {
5382 if (generate_instr_drop(cctx, ISN_CONCAT, 1) == NULL) 5436 if (generate_instr_drop(cctx, ISN_CONCAT, 1) == NULL)
5766 garray_T *stack = &cctx->ctx_type_stack; 5820 garray_T *stack = &cctx->ctx_type_stack;
5767 type_T *type; 5821 type_T *type;
5768 5822
5769 type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 5823 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
5770 if (type != &t_bool && type != &t_number && type != &t_any 5824 if (type != &t_bool && type != &t_number && type != &t_any
5771 && need_type(type, &t_bool, -1, cctx, FALSE) == FAIL) 5825 && need_type(type, &t_bool, -1, cctx, FALSE, FALSE) == FAIL)
5772 return FAIL; 5826 return FAIL;
5773 return OK; 5827 return OK;
5774 } 5828 }
5775 5829
5776 /* 5830 /*
6103 } 6157 }
6104 6158
6105 // Now that we know the type of "var", check that it is a list, now or at 6159 // Now that we know the type of "var", check that it is a list, now or at
6106 // runtime. 6160 // runtime.
6107 vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 6161 vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
6108 if (need_type(vartype, &t_list_any, -1, cctx, FALSE) == FAIL) 6162 if (need_type(vartype, &t_list_any, -1, cctx, FALSE, FALSE) == FAIL)
6109 { 6163 {
6110 drop_scope(cctx); 6164 drop_scope(cctx);
6111 return NULL; 6165 return NULL;
6112 } 6166 }
6113 if (vartype->tt_type == VAR_LIST && vartype->tt_member->tt_type != VAR_ANY) 6167 if (vartype->tt_type == VAR_LIST && vartype->tt_member->tt_type != VAR_ANY)