Patch 9.0.1108
Problem:    Type error when using "any" type and adding a number to a float.
Solution:   Accept both a number and a float. (closes #11753)
Files:      src/vim9compile.c, src/proto/vim9compile.pro, src/structs.h,
            src/vim9instr.c, src/proto/vim9instr.pro, src/vim9cmds.c,
            src/evalfunc.c, src/vim9expr.c, src/vim9type.c, src/vim9execute.c,
            src/testdir/test_vim9_expr.vim


*** ../vim-9.0.1107/src/vim9compile.c   2022-12-23 17:56:21.405511534 +0000
--- src/vim9compile.c   2022-12-29 20:15:50.625658518 +0000
***************
*** 451,456 ****
--- 451,457 ----
  need_type_where(
        type_T  *actual,
        type_T  *expected,
+       int     number_ok,      // expect VAR_FLOAT but VAR_NUMBER is OK
        int     offset,
        where_T where,
        cctx_T  *cctx,
***************
*** 480,486 ****
      // If the actual type can be the expected type add a runtime check.
      if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected))
      {
!       generate_TYPECHECK(cctx, expected, offset,
                                            where.wt_variable, where.wt_index);
        return OK;
      }
--- 481,487 ----
      // If the actual type can be the expected type add a runtime check.
      if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected))
      {
!       generate_TYPECHECK(cctx, expected, number_ok, offset,
                                            where.wt_variable, where.wt_index);
        return OK;
      }
***************
*** 494,499 ****
--- 495,501 ----
  need_type(
        type_T  *actual,
        type_T  *expected,
+       int     number_ok,  // when expected is float number is also OK
        int     offset,
        int     arg_idx,
        cctx_T  *cctx,
***************
*** 503,509 ****
      where_T where = WHERE_INIT;
  
      where.wt_index = arg_idx;
!     return need_type_where(actual, expected, offset, where,
                                                cctx, silent, actual_is_const);
  }
  
--- 505,511 ----
      where_T where = WHERE_INIT;
  
      where.wt_index = arg_idx;
!     return need_type_where(actual, expected, number_ok, offset, where,
                                                cctx, silent, actual_is_const);
  }
  
***************
*** 2000,2007 ****
        // now we can properly check the type
        if (rhs_type != NULL && lhs->lhs_type->tt_member != NULL
                && rhs_type != &t_void
!               && need_type(rhs_type, lhs->lhs_type->tt_member, -2, 0, cctx,
!                                                        FALSE, FALSE) == FAIL)
            return FAIL;
      }
      else
--- 2002,2009 ----
        // now we can properly check the type
        if (rhs_type != NULL && lhs->lhs_type->tt_member != NULL
                && rhs_type != &t_void
!               && need_type(rhs_type, lhs->lhs_type->tt_member, FALSE,
!                                           -2, 0, cctx, FALSE, FALSE) == FAIL)
            return FAIL;
      }
      else
***************
*** 2090,2102 ****
            if (range)
            {
                type = get_type_on_stack(cctx, 1);
!               if (need_type(type, &t_number,
                                            -2, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
            }
            type = get_type_on_stack(cctx, 0);
            if ((dest_type != VAR_BLOB && type->tt_type != VAR_SPECIAL)
!                   && need_type(type, &t_number,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
        }
--- 2092,2104 ----
            if (range)
            {
                type = get_type_on_stack(cctx, 1);
!               if (need_type(type, &t_number, FALSE,
                                            -2, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
            }
            type = get_type_on_stack(cctx, 0);
            if ((dest_type != VAR_BLOB && type->tt_type != VAR_SPECIAL)
!                   && need_type(type, &t_number, FALSE,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
        }
***************
*** 2357,2363 ****
                emsg(_(e_cannot_use_void_value));
                goto theend;
            }
!           if (need_type(stacktype, &t_list_any, -1, 0, cctx,
                                                         FALSE, FALSE) == FAIL)
                goto theend;
            // If a constant list was used we can check the length right here.
--- 2359,2365 ----
                emsg(_(e_cannot_use_void_value));
                goto theend;
            }
!           if (need_type(stacktype, &t_list_any, FALSE, -1, 0, cctx,
                                                         FALSE, FALSE) == FAIL)
                goto theend;
            // If a constant list was used we can check the length right here.
***************
*** 2424,2430 ****
        {
            SOURCING_LNUM = start_lnum;
            if (lhs.lhs_has_type
!                   && need_type(&t_list_string, lhs.lhs_type,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
                goto theend;
        }
--- 2426,2432 ----
        {
            SOURCING_LNUM = start_lnum;
            if (lhs.lhs_has_type
!                   && need_type(&t_list_string, lhs.lhs_type, FALSE,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
                goto theend;
        }
***************
*** 2549,2556 ****
                                && !has_list_index(var_start + lhs.lhs_varlen,
                                                                         cctx))
                            use_type = lhs.lhs_member_type;
!                       if (need_type_where(rhs_type, use_type, -1, where,
!                                               cctx, FALSE, is_const) == FAIL)
                            goto theend;
                    }
                }
--- 2551,2558 ----
                                && !has_list_index(var_start + lhs.lhs_varlen,
                                                                         cctx))
                            use_type = lhs.lhs_member_type;
!                       if (need_type_where(rhs_type, use_type, FALSE, -1,
!                                        where, cctx, FALSE, is_const) == FAIL)
                            goto theend;
                    }
                }
***************
*** 2565,2571 ****
                                || lhs_type == &t_float)
                            && rhs_type->tt_type == VAR_NUMBER)
                        lhs_type = &t_number;
!                   if (*p != '=' && need_type(rhs_type, lhs_type,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
                    goto theend;
                }
--- 2567,2573 ----
                                || lhs_type == &t_float)
                            && rhs_type->tt_type == VAR_NUMBER)
                        lhs_type = &t_number;
!                   if (*p != '=' && need_type(rhs_type, lhs_type, FALSE,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
                    goto theend;
                }
***************
*** 2622,2629 ****
                if (
                    // If variable is float operation with number is OK.
                    !(expected == &t_float && (stacktype == &t_number
!                           || stacktype == &t_number_bool)) &&
!                   need_type(stacktype, expected, -1, 0, cctx,
                                                         FALSE, FALSE) == FAIL)
                    goto theend;
            }
--- 2624,2631 ----
                if (
                    // If variable is float operation with number is OK.
                    !(expected == &t_float && (stacktype == &t_number
!                           || stacktype == &t_number_bool))
!                   && need_type(stacktype, expected, TRUE, -1, 0, cctx,
                                                         FALSE, FALSE) == FAIL)
                    goto theend;
            }
***************
*** 3104,3110 ****
                ufunc->uf_arg_types[arg_idx] = val_type;
            }
            else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx],
!                                      -1, where, &cctx, FALSE, FALSE) == FAIL)
                goto erret;
  
            if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
--- 3106,3112 ----
                ufunc->uf_arg_types[arg_idx] = val_type;
            }
            else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx],
!                               FALSE, -1, where, &cctx, FALSE, FALSE) == FAIL)
                goto erret;
  
            if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
*** ../vim-9.0.1107/src/proto/vim9compile.pro   2022-09-14 00:30:47.077316538 
+0100
--- src/proto/vim9compile.pro   2022-12-29 20:17:52.749562784 +0000
***************
*** 5,13 ****
  int script_is_vim9(void);
  int script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T 
*cstack);
  int check_defined(char_u *p, size_t len, cctx_T *cctx, cstack_T *cstack, int 
is_arg);
! int need_type_where(type_T *actual, type_T *expected, int offset, where_T 
where, cctx_T *cctx, int silent, int actual_is_const);
! int need_type(type_T *actual, type_T *expected, int offset, int arg_idx, 
cctx_T *cctx, int silent, int actual_is_const);
! lvar_T *reserve_local(cctx_T *cctx, char_u *name, size_t len, int isConst, 
type_T *type);
  int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T 
*cctx, cstack_T *cstack);
  imported_T *find_imported(char_u *name, size_t len, int load);
  char_u *may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp);
--- 5,13 ----
  int script_is_vim9(void);
  int script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T 
*cstack);
  int check_defined(char_u *p, size_t len, cctx_T *cctx, cstack_T *cstack, int 
is_arg);
! int need_type_where(type_T *actual, type_T *expected, int number_ok, int 
offset, where_T where, cctx_T *cctx, int silent, int actual_is_const);
! int need_type(type_T *actual, type_T *expected, int number_ok, int offset, 
int arg_idx, cctx_T *cctx, int silent, int actual_is_const);
! lvar_T *reserve_local(cctx_T *cctx, char_u *name, size_t len, int assign, 
type_T *type);
  int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T 
*cctx, cstack_T *cstack);
  imported_T *find_imported(char_u *name, size_t len, int load);
  char_u *may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp);
*** ../vim-9.0.1107/src/structs.h       2022-12-18 21:42:49.010716927 +0000
--- src/structs.h       2022-12-29 20:05:44.254184012 +0000
***************
*** 1460,1465 ****
--- 1460,1471 ----
      type_T    *type_decl;         // declared type or equal to type_current
  } type2_T;
  
+ #define TTFLAG_VARARGS            0x01    // func args ends with "..."
+ #define TTFLAG_BOOL_OK            0x02    // can be converted to bool
+ #define TTFLAG_NUMBER_OK    0x04    // tt_type is VAR_FLOAT, VAR_NUMBER is OK
+ #define TTFLAG_STATIC     0x08    // one of the static types, e.g. t_any
+ #define TTFLAG_CONST      0x10    // cannot be changed
+ 
  typedef enum {
      ACCESS_PRIVATE,   // read/write only inside th class
      ACCESS_READ,      // read everywhere, write only inside th class
***************
*** 1517,1527 ****
      int               obj_copyID;         // used by garbage collection
  };
  
- #define TTFLAG_VARARGS        0x01        // func args ends with "..."
- #define TTFLAG_BOOL_OK        0x02        // can be converted to bool
- #define TTFLAG_STATIC 0x04        // one of the static types, e.g. t_any
- #define TTFLAG_CONST  0x08        // cannot be changed
- 
  /*
   * Structure to hold an internal variable without a name.
   */
--- 1523,1528 ----
*** ../vim-9.0.1107/src/vim9instr.c     2022-12-18 22:01:38.869926641 +0000
--- src/vim9instr.c     2022-12-29 20:46:40.946278300 +0000
***************
*** 576,581 ****
--- 576,582 ----
  generate_TYPECHECK(
        cctx_T      *cctx,
        type_T      *expected,
+       int         number_ok,      // add TTFLAG_NUMBER_OK flag
        int         offset,
        int         is_var,
        int         argidx)
***************
*** 585,591 ****
      RETURN_OK_IF_SKIP(cctx);
      if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL)
        return FAIL;
!     isn->isn_arg.type.ct_type = alloc_type(expected);
      isn->isn_arg.type.ct_off = (int8_T)offset;
      isn->isn_arg.type.ct_is_var = is_var;
      isn->isn_arg.type.ct_arg_idx = (int8_T)argidx;
--- 586,606 ----
      RETURN_OK_IF_SKIP(cctx);
      if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL)
        return FAIL;
!     type_T *tt;
!     if (expected->tt_type == VAR_FLOAT && number_ok)
!     {
!       // always allocate, also for static types
!       tt = ALLOC_ONE(type_T);
!       if (tt != NULL)
!       {
!           *tt = *expected;
!           tt->tt_flags |= TTFLAG_NUMBER_OK;
!       }
!     }
!     else
!       tt = alloc_type(expected);
! 
!     isn->isn_arg.type.ct_type = tt;
      isn->isn_arg.type.ct_off = (int8_T)offset;
      isn->isn_arg.type.ct_is_var = is_var;
      isn->isn_arg.type.ct_arg_idx = (int8_T)argidx;
***************
*** 1601,1607 ****
      if (maptype != NULL && maptype[0].type_decl->tt_member != NULL
                                  && maptype[0].type_decl->tt_member != &t_any)
        // Check that map() didn't change the item types.
!       generate_TYPECHECK(cctx, maptype[0].type_decl, -1, FALSE, 1);
  
      return OK;
  }
--- 1616,1622 ----
      if (maptype != NULL && maptype[0].type_decl->tt_member != NULL
                                  && maptype[0].type_decl->tt_member != &t_any)
        // Check that map() didn't change the item types.
!       generate_TYPECHECK(cctx, maptype[0].type_decl, FALSE, -1, FALSE, 1);
  
      return OK;
  }
***************
*** 1625,1631 ****
        return FAIL;
      item_type = get_type_on_stack(cctx, 0);
      expected = list_type->tt_member;
!     if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL)
        return FAIL;
  
      if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
--- 1640,1646 ----
        return FAIL;
      item_type = get_type_on_stack(cctx, 0);
      expected = list_type->tt_member;
!     if (need_type(item_type, expected, FALSE, -1, 0, cctx, FALSE, FALSE) == 
FAIL)
        return FAIL;
  
      if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
***************
*** 1648,1654 ****
      if (arg_type_modifiable(get_decl_type_on_stack(cctx, 1), 1) == FAIL)
        return FAIL;
      item_type = get_type_on_stack(cctx, 0);
!     if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
        return FAIL;
  
      if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
--- 1663,1670 ----
      if (arg_type_modifiable(get_decl_type_on_stack(cctx, 1), 1) == FAIL)
        return FAIL;
      item_type = get_type_on_stack(cctx, 0);
!     if (need_type(item_type, &t_number, FALSE,
!                                           -1, 0, cctx, FALSE, FALSE) == FAIL)
        return FAIL;
  
      if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
***************
*** 1713,1720 ****
                expected = &t_any;
            else
                expected = ufunc->uf_va_type->tt_member;
!           if (need_type(actual, expected, -argcount + i, i + 1, cctx,
!                                                         TRUE, FALSE) == FAIL)
            {
                arg_type_mismatch(expected, actual, i + 1);
                return FAIL;
--- 1729,1736 ----
                expected = &t_any;
            else
                expected = ufunc->uf_va_type->tt_member;
!           if (need_type(actual, expected, FALSE,
!                             -argcount + i, i + 1, cctx, TRUE, FALSE) == FAIL)
            {
                arg_type_mismatch(expected, actual, i + 1);
                return FAIL;
***************
*** 1821,1828 ****
                    expected = &t_any;
                else
                    expected = type->tt_args[i];
!               if (need_type(actual, expected, offset, i + 1,
!                                                   cctx, TRUE, FALSE) == FAIL)
                {
                    arg_type_mismatch(expected, actual, i + 1);
                    return FAIL;
--- 1837,1844 ----
                    expected = &t_any;
                else
                    expected = type->tt_args[i];
!               if (need_type(actual, expected, FALSE,
!                                    offset, i + 1, cctx, TRUE, FALSE) == FAIL)
                {
                    arg_type_mismatch(expected, actual, i + 1);
                    return FAIL;
*** ../vim-9.0.1107/src/proto/vim9instr.pro     2022-12-18 21:42:49.014716925 
+0000
--- src/proto/vim9instr.pro     2022-12-29 20:09:27.981976958 +0000
***************
*** 15,21 ****
  int generate_CONCAT(cctx_T *cctx, int count);
  int generate_2BOOL(cctx_T *cctx, int invert, int offset);
  int generate_COND2BOOL(cctx_T *cctx);
! int generate_TYPECHECK(cctx_T *cctx, type_T *expected, int offset, int 
is_var, int argidx);
  int generate_SETTYPE(cctx_T *cctx, type_T *expected);
  int generate_tv_PUSH(cctx_T *cctx, typval_T *tv);
  int generate_PUSHNR(cctx_T *cctx, varnumber_T number);
--- 15,21 ----
  int generate_CONCAT(cctx_T *cctx, int count);
  int generate_2BOOL(cctx_T *cctx, int invert, int offset);
  int generate_COND2BOOL(cctx_T *cctx);
! int generate_TYPECHECK(cctx_T *cctx, type_T *expected, int number_ok, int 
offset, int is_var, int argidx);
  int generate_SETTYPE(cctx_T *cctx, type_T *expected);
  int generate_tv_PUSH(cctx_T *cctx, typval_T *tv);
  int generate_PUSHNR(cctx_T *cctx, varnumber_T number);
*** ../vim-9.0.1107/src/vim9cmds.c      2022-12-25 15:59:19.993863341 +0000
--- src/vim9cmds.c      2022-12-29 20:14:12.365737240 +0000
***************
*** 1045,1051 ****
                if (lhs_type == &t_any)
                    lhs_type = item_type;
                else if (item_type != &t_unknown
!                       && need_type_where(item_type, lhs_type, -1,
                                            where, cctx, FALSE, FALSE) == FAIL)
                    goto failed;
                var_lvar = reserve_local(cctx, arg, varlen, ASSIGN_FINAL,
--- 1045,1051 ----
                if (lhs_type == &t_any)
                    lhs_type = item_type;
                else if (item_type != &t_unknown
!                       && need_type_where(item_type, lhs_type, FALSE, -1,
                                            where, cctx, FALSE, FALSE) == FAIL)
                    goto failed;
                var_lvar = reserve_local(cctx, arg, varlen, ASSIGN_FINAL,
***************
*** 2469,2475 ****
        if (compile_assign_lhs(arg, lhs, CMD_redir,
                                         FALSE, FALSE, FALSE, 1, cctx) == FAIL)
            return NULL;
!       if (need_type(&t_string, lhs->lhs_member_type,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
            return NULL;
        if (cctx->ctx_skip == SKIP_YES)
--- 2469,2475 ----
        if (compile_assign_lhs(arg, lhs, CMD_redir,
                                         FALSE, FALSE, FALSE, 1, cctx) == FAIL)
            return NULL;
!       if (need_type(&t_string, lhs->lhs_member_type, FALSE,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
            return NULL;
        if (cctx->ctx_skip == SKIP_YES)
***************
*** 2551,2557 ****
            int save_flags = cmdmod.cmod_flags;
  
            generate_LEGACY_EVAL(cctx, p);
!           if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, -1,
                                                0, cctx, FALSE, FALSE) == FAIL)
                return NULL;
            cmdmod.cmod_flags |= CMOD_LEGACY;
--- 2551,2557 ----
            int save_flags = cmdmod.cmod_flags;
  
            generate_LEGACY_EVAL(cctx, p);
!           if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, FALSE, -1,
                                                0, cctx, FALSE, FALSE) == FAIL)
                return NULL;
            cmdmod.cmod_flags |= CMOD_LEGACY;
***************
*** 2580,2587 ****
            }
            else
            {
!               if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1,
!                                               0, cctx, FALSE, FALSE) == FAIL)
                    return NULL;
            }
        }
--- 2580,2587 ----
            }
            else
            {
!               if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, FALSE,
!                                           -1, 0, cctx, FALSE, FALSE) == FAIL)
                    return NULL;
            }
        }
*** ../vim-9.0.1107/src/evalfunc.c      2022-12-20 20:01:09.620090910 +0000
--- src/evalfunc.c      2022-12-29 20:13:38.857764490 +0000
***************
*** 215,221 ****
        type_T          *actual,
        argcontext_T    *context)
  {
!     return need_type(actual, expected,
            context->arg_idx - context->arg_count, context->arg_idx + 1,
            context->arg_cctx, FALSE, FALSE);
  }
--- 215,221 ----
        type_T          *actual,
        argcontext_T    *context)
  {
!     return need_type(actual, expected, FALSE,
            context->arg_idx - context->arg_count, context->arg_idx + 1,
            context->arg_cctx, FALSE, FALSE);
  }
***************
*** 229,235 ****
        type_T          *actual,
        argcontext_T    *context)
  {
!     if (need_type(actual, expected,
            context->arg_idx - context->arg_count, context->arg_idx + 1,
            context->arg_cctx, FALSE, FALSE) == FAIL)
        return FAIL;
--- 229,235 ----
        type_T          *actual,
        argcontext_T    *context)
  {
!     if (need_type(actual, expected, FALSE,
            context->arg_idx - context->arg_count, context->arg_idx + 1,
            context->arg_cctx, FALSE, FALSE) == FAIL)
        return FAIL;
*** ../vim-9.0.1107/src/vim9expr.c      2022-12-27 20:54:35.940837899 +0000
--- src/vim9expr.c      2022-12-29 20:17:04.665600223 +0000
***************
*** 99,111 ****
        vartype = VAR_DICT;
      if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
      {
!       if (need_type(idxtype, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
            return FAIL;
        if (is_slice)
        {
            idxtype = get_type_on_stack(cctx, 1);
!           if (need_type(idxtype, &t_number, -2, 0, cctx,
!                                                        FALSE, FALSE) == FAIL)
                return FAIL;
        }
      }
--- 99,112 ----
        vartype = VAR_DICT;
      if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
      {
!       if (need_type(idxtype, &t_number, FALSE,
!                                           -1, 0, cctx, FALSE, FALSE) == FAIL)
            return FAIL;
        if (is_slice)
        {
            idxtype = get_type_on_stack(cctx, 1);
!           if (need_type(idxtype, &t_number, FALSE,
!                                           -2, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
        }
      }
***************
*** 135,142 ****
        }
        else
        {
!           if (need_type(typep->type_curr, &t_dict_any, -2, 0, cctx,
!                                                        FALSE, FALSE) == FAIL)
                return FAIL;
            typep->type_curr = &t_any;
            typep->type_decl = &t_any;
--- 136,143 ----
        }
        else
        {
!           if (need_type(typep->type_curr, &t_dict_any, FALSE,
!                                           -2, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
            typep->type_curr = &t_any;
            typep->type_decl = &t_any;
***************
*** 1725,1731 ****
        // This requires a runtime type check.
        return generate_COND2BOOL(cctx);
  
!     return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE);
  }
  
  /*
--- 1726,1732 ----
        // This requires a runtime type check.
        return generate_COND2BOOL(cctx);
  
!     return need_type(type, &t_bool, FALSE, -1, 0, cctx, FALSE, FALSE);
  }
  
  /*
***************
*** 1759,1765 ****
        {
            type_T *type = get_type_on_stack(cctx, 0);
            if (type->tt_type != VAR_FLOAT && need_type(type, &t_number,
!                                           -1, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
  
            // only '-' has an effect, for '+' we only check the type
--- 1760,1766 ----
        {
            type_T *type = get_type_on_stack(cctx, 0);
            if (type->tt_type != VAR_FLOAT && need_type(type, &t_number,
!                                    FALSE, -1, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
  
            // only '-' has an effect, for '+' we only check the type
***************
*** 2517,2524 ****
        actual = get_type_on_stack(cctx, 0);
        if (check_type_maybe(want_type, actual, FALSE, where) != OK)
        {
!           if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE)
!                                                                      == FAIL)
                return FAIL;
        }
      }
--- 2518,2525 ----
        actual = get_type_on_stack(cctx, 0);
        if (check_type_maybe(want_type, actual, FALSE, where) != OK)
        {
!           if (need_type(actual, want_type, FALSE,
!                                           -1, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
        }
      }
***************
*** 2759,2765 ****
        {
            type_T      *t = get_type_on_stack(cctx, 0);
  
!           if (need_type(t, &t_number, 0, 0, cctx, FALSE, FALSE) == FAIL)
            {
                emsg(_(e_bitshift_ops_must_be_number));
                return FAIL;
--- 2760,2766 ----
        {
            type_T      *t = get_type_on_stack(cctx, 0);
  
!           if (need_type(t, &t_number, FALSE, 0, 0, cctx, FALSE, FALSE) == 
FAIL)
            {
                emsg(_(e_bitshift_ops_must_be_number));
                return FAIL;
***************
*** 2814,2821 ****
        }
        else
        {
!           if (need_type(get_type_on_stack(cctx, 0), &t_number, 0, 0, cctx,
!                       FALSE, FALSE) == FAIL)
            {
                emsg(_(e_bitshift_ops_must_be_number));
                return FAIL;
--- 2815,2822 ----
        }
        else
        {
!           if (need_type(get_type_on_stack(cctx, 0), &t_number, FALSE,
!                                            0, 0, cctx, FALSE, FALSE) == FAIL)
            {
                emsg(_(e_bitshift_ops_must_be_number));
                return FAIL;
*** ../vim-9.0.1107/src/vim9type.c      2022-12-27 17:24:55.270083348 +0000
--- src/vim9type.c      2022-12-29 20:22:52.737334749 +0000
***************
*** 813,818 ****
--- 813,823 ----
                                        && (actual->tt_flags & TTFLAG_BOOL_OK))
                // Using number 0 or 1 for bool is OK.
                return OK;
+           if (expected->tt_type == VAR_FLOAT
+                   && (expected->tt_flags & TTFLAG_NUMBER_OK)
+                                       && actual->tt_type == VAR_NUMBER)
+               // Using number where float is expected is OK here.
+               return OK;
            if (give_msg)
                type_mismatch_where(expected, actual, where);
            return FAIL;
***************
*** 848,854 ****
            {
                int i;
  
!               for (i = 0; i < expected->tt_argcount && i < 
actual->tt_argcount; ++i)
                    // Allow for using "any" argument type, lambda's have them.
                    if (actual->tt_args[i] != &t_any && check_type(
                            expected->tt_args[i], actual->tt_args[i], FALSE,
--- 853,860 ----
            {
                int i;
  
!               for (i = 0; i < expected->tt_argcount
!                                              && i < actual->tt_argcount; ++i)
                    // Allow for using "any" argument type, lambda's have them.
                    if (actual->tt_args[i] != &t_any && check_type(
                            expected->tt_args[i], actual->tt_args[i], FALSE,
*** ../vim-9.0.1107/src/vim9execute.c   2022-12-24 21:23:59.578929527 +0000
--- src/vim9execute.c   2022-12-29 20:30:10.752199871 +0000
***************
*** 6872,6887 ****
            case ISN_CHECKTYPE:
                  {
                      checktype_T   *ct = &iptr->isn_arg.type;
!                     char          *tofree;
  
                      if (ct->ct_arg_idx == 0)
                          smsg("%s%4d CHECKTYPE %s stack[%d]", pfx, current,
!                                         type_name(ct->ct_type, &tofree),
                                          (int)ct->ct_off);
                      else
                          smsg("%s%4d CHECKTYPE %s stack[%d] %s %d",
                                          pfx, current,
!                                         type_name(ct->ct_type, &tofree),
                                          (int)ct->ct_off,
                                          ct->ct_is_var ? "var": "arg",
                                          (int)ct->ct_arg_idx);
--- 6872,6894 ----
            case ISN_CHECKTYPE:
                  {
                      checktype_T   *ct = &iptr->isn_arg.type;
!                     char          *tofree = NULL;
!                     char          *typename;
! 
!                     if (ct->ct_type->tt_type == VAR_FLOAT
!                             && (ct->ct_type->tt_flags & TTFLAG_NUMBER_OK))
!                         typename = "float|number";
!                     else
!                         typename = type_name(ct->ct_type, &tofree);
  
                      if (ct->ct_arg_idx == 0)
                          smsg("%s%4d CHECKTYPE %s stack[%d]", pfx, current,
!                                         typename,
                                          (int)ct->ct_off);
                      else
                          smsg("%s%4d CHECKTYPE %s stack[%d] %s %d",
                                          pfx, current,
!                                         typename,
                                          (int)ct->ct_off,
                                          ct->ct_is_var ? "var": "arg",
                                          (int)ct->ct_arg_idx);
*** ../vim-9.0.1107/src/testdir/test_vim9_expr.vim      2022-12-27 
20:54:35.940837899 +0000
--- src/testdir/test_vim9_expr.vim      2022-12-29 20:40:49.182807310 +0000
***************
*** 2033,2038 ****
--- 2033,2066 ----
    v9.CheckScriptFailure(['vim9script', "var x = <number>"], 'E15:', 2)
    v9.CheckDefAndScriptFailure(["var x = <number >123"], 'E1068:', 1)
    v9.CheckDefAndScriptFailure(["var x = <number 123"], 'E1104:', 1)
+ 
+   lines =<< trim END
+       vim9script
+ 
+       def Sum(v: any): float
+         var sum = 0.0
+         sum += v
+         return sum
+       enddef
+ 
+       const kk = 1
+       echo Sum(kk)
+   END
+   v9.CheckScriptSuccess(lines)
+ 
+   lines =<< trim END
+       vim9script
+ 
+       def Sum(v: any): float
+         var sum = 0.0
+         sum += <float>v
+         return sum
+       enddef
+ 
+       const kk = 1
+       Sum(kk)
+   END
+   v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected float but got 
number')
  enddef
  
  " test low level expression
*** ../vim-9.0.1107/src/version.c       2022-12-27 20:54:35.940837899 +0000
--- src/version.c       2022-12-29 20:47:22.626221016 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1108,
  /**/

-- 
ARTHUR:  No, hang on!  Just answer the five questions ...
GALAHAD: Three questions ...
ARTHUR:  Three questions ...  And we shall watch ... and pray.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221229205656.D270E1C0AA3%40moolenaar.net.

Raspunde prin e-mail lui