]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.4285: Vim9: type of item in for loop not checked properly v8.2.4285
authorBram Moolenaar <Bram@vim.org>
Wed, 2 Feb 2022 16:20:26 +0000 (16:20 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 2 Feb 2022 16:20:26 +0000 (16:20 +0000)
Problem:    Vim9: type of item in for loop not checked properly.
Solution:   Adjust the type checking. (closes #9683)

src/proto/vim9compile.pro
src/testdir/test_vim9_script.vim
src/version.c
src/vim9cmds.c
src/vim9compile.c

index cb95fdfb6bc34819b0f0570d967a4a0ca7ae112f..b7f7539215b91fb32f06faa0e9d73855a5139628 100644 (file)
@@ -4,6 +4,7 @@ int arg_exists(char_u *name, size_t len, int *idxp, type_T **type, int *gen_load
 int script_is_vim9(void);
 int script_var_exists(char_u *name, size_t len, cctx_T *cctx);
 int check_defined(char_u *p, size_t len, cctx_T *cctx, 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);
index a3f28f1e7246a6c4e68b921d6100750e5c95343d..767abd4855cc5c533628ab50d2a0ec3b4b87f54f 100644 (file)
@@ -2011,7 +2011,7 @@ def Test_for_loop_fails()
         echo k v
       endfor
   END
-  v9.CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected job but got string', 2)
+  v9.CheckDefExecAndScriptFailure(lines, ['E1013: Argument 1: type mismatch, expected job but got string', 'E1012: Type mismatch; expected job but got string'], 2)
 
   lines =<< trim END
       var i = 0
@@ -2036,6 +2036,22 @@ def Test_for_loop_fails()
       endfor
   END
   v9.CheckDefExecAndScriptFailure(lines, ['E461:', 'E1017:'])
+
+  lines =<< trim END
+      var l: list<dict<any>> = [{a: 1, b: 'x'}]
+      for item: dict<number> in l
+        echo item
+      endfor
+  END
+  v9.CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<number> but got dict<any>')
+
+  lines =<< trim END
+      var l: list<dict<any>> = [{n: 1}]
+      for item: dict<number> in l
+        item->extend({s: ''})
+      endfor
+  END
+  v9.CheckDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string>')
 enddef
 
 def Test_for_loop_script_var()
index 7417143c6714e719fbcd4d93d050e37857c0c2a1..2c623671c73e57d4e3a32362a29c6401b522bcc7 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4285,
 /**/
     4284,
 /**/
index 716a4041113e25a99c718a78ea03838bb110ec25..90b61dbb34ba318a8f00b434230d1ba96ff88375 100644 (file)
@@ -990,11 +990,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
                if (lhs_type == &t_any)
                    lhs_type = item_type;
                else if (item_type != &t_unknown
-                           && (item_type == &t_any
-                             ? need_type(item_type, lhs_type,
-                                                    -1, 0, cctx, FALSE, FALSE)
-                             : check_type(lhs_type, item_type, TRUE, where))
-                           == FAIL)
+                       && need_type_where(item_type, lhs_type, -1,
+                                           where, cctx, FALSE, FALSE) == FAIL)
                    goto failed;
                var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type);
                if (var_lvar == NULL)
@@ -1003,8 +1000,6 @@ compile_for(char_u *arg_start, cctx_T *cctx)
 
                if (semicolon && idx == var_count - 1)
                    var_lvar->lv_type = vartype;
-               else
-                   var_lvar->lv_type = item_type;
                generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
            }
 
index 9ad1e7ddc97bd2fb8573c6a202862c88ece81b73..9dbd1198ddb93e8c1879accd9e904743d5e616fa 100644 (file)
@@ -386,7 +386,7 @@ use_typecheck(type_T *actual, type_T *expected)
  * If "actual_is_const" is TRUE then the type won't change at runtime, do not
  * generate a TYPECHECK.
  */
-    static int
+    int
 need_type_where(
        type_T  *actual,
        type_T  *expected,