]> granicus.if.org Git - vim/commitdiff
patch 8.2.3326: Vim9: no error passing an empty list of the wrong type v8.2.3326
authorBram Moolenaar <Bram@vim.org>
Tue, 10 Aug 2021 20:52:02 +0000 (22:52 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 10 Aug 2021 20:52:02 +0000 (22:52 +0200)
Problem:    Vim9: no error passing an empty list of the wrong type.
Solution:   Use ISN_SETTYPE also for "list<any>". (closes #8732)

src/testdir/test_vim9_disassemble.vim
src/testdir/test_vim9_func.vim
src/version.c
src/vim9compile.c

index 9eaa8647f3638bf954ad8d844e535f2ce550db1e..1d1730e00426ecc6036f68b80e4e0a2b44eb3e13 100644 (file)
@@ -435,6 +435,7 @@ def Test_disassemble_list_assign()
         '\d STORE $1\_s*' ..
         'var l: list<any>\_s*' ..
         '\d NEWLIST size 0\_s*' ..
+        '\d SETTYPE list<any>\_s*' ..
         '\d STORE $2\_s*' ..
         '\[x, y; l\] = g:stringlist\_s*' ..
         '\d LOADG g:stringlist\_s*' ..
index de7b980fde946ef837a685e02c980a3e82ba26c4..f8d3f59b2e3a510d6cf46021ac22c85498674f2a 100644 (file)
@@ -2930,6 +2930,27 @@ def Test_check_func_arg_types()
   CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
 enddef
 
+def Test_list_any_type_checked()
+  var lines =<< trim END
+      vim9script
+      def Foo()
+        --decl--
+        Bar(l)
+      enddef
+      def Bar(ll: list<dict<any>>)
+      enddef
+      Foo()
+  END
+  lines[2] = 'var l: list<any>'
+  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2)
+
+  lines[2] = 'var l: list<any> = []'
+  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2)
+
+  lines[2] = 'var l: list<any> = [11]'
+  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
+enddef
+
 def Test_compile_error()
   var lines =<< trim END
     def g:Broken()
index 04b5749bf191cd60804794c8e3a9bc875eca143e..5383ba3440acd9e8c3e2deefcc6536c05c7b7510 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3326,
 /**/
     3325,
 /**/
index 127d5a69d4d3a756b0377ef9182ceffa139ec842..c2becbe5dec4331a53f13bd332cb85379a4ec8b5 100644 (file)
@@ -1598,7 +1598,7 @@ generate_NEWLIST(cctx_T *cctx, int count)
 
     // get the member type from all the items on the stack.
     if (count == 0)
-       member = &t_void;
+       member = &t_unknown;
     else
        member = get_member_type_from_stack(
            ((type_T **)stack->ga_data) + stack->ga_len, count, 1,
@@ -7190,10 +7190,15 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
                    && (lhs.lhs_type->tt_type == VAR_DICT
                                          || lhs.lhs_type->tt_type == VAR_LIST)
                    && lhs.lhs_type->tt_member != NULL
-                   && lhs.lhs_type->tt_member != &t_any
+                   && !(lhs.lhs_type->tt_member == &t_any
+                           && oplen > 0
+                           && rhs_type != NULL
+                           && rhs_type->tt_type == lhs.lhs_type->tt_type
+                           && rhs_type->tt_member != &t_unknown)
                    && lhs.lhs_type->tt_member != &t_unknown)
                // Set the type in the list or dict, so that it can be checked,
-               // also in legacy script.
+               // also in legacy script.  Not for "list<any> = val", then the
+               // type of "val" is used.
                generate_SETTYPE(cctx, lhs.lhs_type);
 
            if (generate_store_lhs(cctx, &lhs, instr_count) == FAIL)