]> granicus.if.org Git - vim/commitdiff
patch 8.2.3997: Vim9: not enough testing for extend() and map() v8.2.3997
authorBram Moolenaar <Bram@vim.org>
Tue, 4 Jan 2022 15:54:38 +0000 (15:54 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 4 Jan 2022 15:54:38 +0000 (15:54 +0000)
Problem:    Vim9: not enough testing for extend() and map().
Solution:   Add more test cases.  Fix uncovered problems.  Remove unused type
            fields.

src/dict.c
src/list.c
src/structs.h
src/testdir/test_vim9_builtin.vim
src/testdir/test_vim9_disassemble.vim
src/version.c
src/vim9compile.c

index 27cde11a3fbad815332e30eb8e41e7bcb581c2e5..f39be72af7d2ccd8bbca6edeac3ed76bd323628e 100644 (file)
@@ -109,8 +109,6 @@ dict_free_contents(dict_T *d)
     hashtab_free_contents(&d->dv_hashtab);
     free_type(d->dv_type);
     d->dv_type = NULL;
-    free_type(d->dv_decl_type);
-    d->dv_decl_type = NULL;
 }
 
 /*
index 6ad3e9211ef7c5b08ab75b197d1848722d521221..aadc7233d0359c0bf908298edcb65c55bea16ef9 100644 (file)
@@ -271,7 +271,6 @@ list_free_list(list_T  *l)
        l->lv_used_next->lv_used_prev = l->lv_used_prev;
 
     free_type(l->lv_type);
-    free_type(l->lv_decl_type);
     vim_free(l);
 }
 
@@ -1026,8 +1025,6 @@ flatten_common(typval_T *argvars, typval_T *rettv, int make_copy)
        // The type will change.
        free_type(l->lv_type);
        l->lv_type = NULL;
-       free_type(l->lv_decl_type);
-       l->lv_decl_type = NULL;
     }
     else
     {
@@ -1223,7 +1220,6 @@ list_copy(list_T *orig, int deep, int copyID)
     if (copy != NULL)
     {
        copy->lv_type = alloc_type(orig->lv_type);
-       copy->lv_decl_type = alloc_type(orig->lv_decl_type);
        if (copyID != 0)
        {
            // Do this before adding the items, because one of the items may
index 7d040eb6f480836cbb0bffb1c452e7951316541e..2da16bf6eefbda025b14bec2482cbde83d48045f 100644 (file)
@@ -1513,7 +1513,6 @@ struct listvar_S
        } mat;
     } lv_u;
     type_T     *lv_type;       // current type, allocated by alloc_type()
-    type_T     *lv_decl_type;  // declared type, allocated by alloc_type()
     list_T     *lv_copylist;   // copied list used by deepcopy()
     list_T     *lv_used_next;  // next list in used lists list
     list_T     *lv_used_prev;  // previous list in used lists list
@@ -1578,7 +1577,6 @@ struct dictvar_S
     int                dv_copyID;      // ID used by deepcopy()
     hashtab_T  dv_hashtab;     // hashtab that refers to the items
     type_T     *dv_type;       // current type, allocated by alloc_type()
-    type_T     *dv_decl_type;  // declared type, allocated by alloc_type()
     dict_T     *dv_copydict;   // copied dict used by deepcopy()
     dict_T     *dv_used_next;  // next dict in used dicts list
     dict_T     *dv_used_prev;  // previous dict in used dicts list
index d957c1502daa13cdefac0dab64c2b5138f39d79b..eb86a03b9131f3c92cdcbcc17003baf6d83178c8 100644 (file)
@@ -979,6 +979,10 @@ def Test_extend_arg_types()
       var res: list<dict<any>>
       extend(res, mapnew([1, 2], (_, v) => ({})))
       assert_equal([{}, {}], res)
+
+      var dany: dict<any> = {a: 0}
+      dany->extend({b: 'x'})
+      assert_equal({a: 0, b: 'x'}, dany)
   END
   CheckDefAndScriptSuccess(lines)
 
@@ -2151,9 +2155,29 @@ def Test_map()
   CheckDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1'])
 
   # type of dict remains dict<any> even when type of values changes
-  var d: dict<any> = {a: 0}
-  d->map((k, v) => true)
-  d->map((k, v) => 'x')
+  # same for list
+  var lines =<< trim END
+      var d: dict<any> = {a: 0}
+      d->map((k, v) => true)
+      d->map((k, v) => 'x')
+      assert_equal({a: 'x'}, d)
+
+      d = {a: 0}
+      g:gd = d
+      map(g:gd, (k, v) => true)
+      assert_equal({a: true}, g:gd)
+
+      var l: list<any> = [0]
+      l->map((k, v) => true)
+      l->map((k, v) => 'x')
+      assert_equal(['x'], l)
+
+      l = [1]
+      g:gl = l
+      map(g:gl, (k, v) => true)
+      assert_equal([true], g:gl)
+  END
+  CheckDefAndScriptSuccess(lines)
 enddef
 
 def Test_map_failure()
@@ -2175,6 +2199,13 @@ def Test_map_failure()
   CheckScriptFailure(lines, 'E1013:')
   au! BufReadPost
   delete('Xtmpfile')
+
+  lines =<< trim END
+      var d: dict<number> = {a: 1}
+      g:gd = d
+      map(g:gd, (k, v) => true)
+  END
+  CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got bool')
 enddef
 
 def Test_map_function_arg()
index d4a5309d996141db3f588e1f48fa773eb0166e91..3a7642f7c27e026c606f015b6fe2f38da8867884 100644 (file)
@@ -455,6 +455,7 @@ def Test_disassemble_list_assign()
         '\d\+ CHECKTYPE string stack\[-1\] arg 2\_s*' ..
         '\d\+ STORE $1\_s*' ..
         '\d\+ SLICE 2\_s*' ..
+        '\d\+ SETTYPE list<any>\_s*' ..
         '\d\+ STORE $2\_s*' ..
         '\d\+ RETURN void',
         res)
index 4d15dbf662839ceaf528c2bc78688fa75e12c98e..170c0c2e626c1ba61dc452fbad5a515320762959 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3997,
 /**/
     3996,
 /**/
index a243e6435313e0c1ae7d60c1e2feb478a2901e15..cccf02c2c52cb57d139ad4a57804cbc7f01ab32d 100644 (file)
@@ -2279,14 +2279,12 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
                // ":const var": lock the value, but not referenced variables
                generate_LOCKCONST(cctx);
 
-           if (is_decl
-                   && (lhs.lhs_type->tt_type == VAR_DICT
+           if ((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_unknown)
                // Set the type in the list or dict, so that it can be checked,
-               // also in legacy script.  Not for "list<any> = val", then the
-               // type of "val" is used.
+               // also in legacy script.
                generate_SETTYPE(cctx, lhs.lhs_type);
 
            if (!skip_store && generate_store_lhs(cctx, &lhs,