Patch 8.2.3117
Problem:    Vim9: type not properly checked in for loop.
Solution:   Have items() return a list of lists.  Add runtime type checks.
            (closes #8515)
Files:      src/evalfunc.c, src/globals.h, src/vim9compile.c,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.3116/src/evalfunc.c      2021-07-04 15:54:04.935754560 +0200
--- src/evalfunc.c      2021-07-07 20:53:23.168084250 +0200
***************
*** 522,527 ****
--- 522,532 ----
      return &t_list_dict_any;
  }
      static type_T *
+ ret_list_items(int argcount, type_T **argtypes UNUSED)
+ {
+     return &t_list_list_any;
+ }
+     static type_T *
  ret_dict_any(int argcount UNUSED, type_T **argtypes UNUSED)
  {
      return &t_dict_any;
***************
*** 1166,1172 ****
      {"isnan",         1, 1, FEARG_1,      arg1_float_or_nr,
                        ret_number_bool,    MATH_FUNC(f_isnan)},
      {"items",         1, 1, FEARG_1,      arg1_dict,
!                       ret_list_any,       f_items},
      {"job_getchannel",        1, 1, FEARG_1,      NULL,
                        ret_channel,        JOB_FUNC(f_job_getchannel)},
      {"job_info",      0, 1, FEARG_1,      NULL,
--- 1171,1177 ----
      {"isnan",         1, 1, FEARG_1,      arg1_float_or_nr,
                        ret_number_bool,    MATH_FUNC(f_isnan)},
      {"items",         1, 1, FEARG_1,      arg1_dict,
!                       ret_list_items,     f_items},
      {"job_getchannel",        1, 1, FEARG_1,      NULL,
                        ret_channel,        JOB_FUNC(f_job_getchannel)},
      {"job_info",      0, 1, FEARG_1,      NULL,
***************
*** 3687,3692 ****
--- 3692,3698 ----
  {
      if (argcount == 1 && argtypes[0]->tt_type == VAR_STRING)
        return &t_func_any;
+     // Need to check the type at runtime, the function may be defined later.
      return &t_func_unknown;
  }
  
*** ../vim-8.2.3116/src/globals.h       2021-07-04 18:28:09.775780576 +0200
--- src/globals.h       2021-07-07 20:54:12.932020659 +0200
***************
*** 441,446 ****
--- 441,447 ----
  EXTERN type_T t_list_string INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, &t_string, 
NULL);
  EXTERN type_T t_list_job INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, &t_job, NULL);
  EXTERN type_T t_list_dict_any INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, 
&t_dict_any, NULL);
+ EXTERN type_T t_list_list_any INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, 
&t_list_any, NULL);
  
  EXTERN type_T t_dict_bool INIT6(VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL);
  EXTERN type_T t_dict_number INIT6(VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, 
NULL);
*** ../vim-8.2.3116/src/vim9compile.c   2021-07-05 21:41:44.782616398 +0200
--- src/vim9compile.c   2021-07-07 21:03:49.119174075 +0200
***************
*** 7932,7939 ****
            if (lhs_type == &t_any)
                lhs_type = item_type;
            else if (item_type != &t_unknown
!                      && !(var_list && item_type == &t_any)
!                      && check_type(lhs_type, item_type, TRUE, where) == FAIL)
                goto failed;
            var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type);
            if (var_lvar == NULL)
--- 7932,7942 ----
            if (lhs_type == &t_any)
                lhs_type = item_type;
            else if (item_type != &t_unknown
!                       && ((var_list && item_type == &t_any)
!                         ? need_type(item_type, lhs_type,
!                                                    -1, 0, cctx, FALSE, FALSE)
!                         : check_type(lhs_type, item_type, TRUE, where))
!                       == FAIL)
                goto failed;
            var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type);
            if (var_lvar == NULL)
*** ../vim-8.2.3116/src/testdir/test_vim9_script.vim    2021-07-05 
22:22:57.005685230 +0200
--- src/testdir/test_vim9_script.vim    2021-07-07 21:07:33.810812104 +0200
***************
*** 2573,2578 ****
--- 2573,2586 ----
        endfor
    END
    CheckDefAndScriptFailure(lines, 'E1059:', 1)
+ 
+   lines =<< trim END
+       var d: dict<number> = {a: 1, b: 2}
+       for [k: job, v: job] in d->items()
+         echo k v
+       endfor
+   END
+   CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected job but 
got string', 2)
  enddef
  
  def Test_for_loop_script_var()
*** ../vim-8.2.3116/src/version.c       2021-07-07 20:10:40.628454961 +0200
--- src/version.c       2021-07-07 21:07:54.026779053 +0200
***************
*** 757,758 ****
--- 757,760 ----
  {   /* Add new patch number below this line */
+ /**/
+     3117,
  /**/

-- 
I AM THANKFUL...
...for the piles of laundry and ironing because it means I
have plenty of clothes to wear.

 /// 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/202107071921.167JLx383425588%40masaka.moolenaar.net.

Raspunde prin e-mail lui