Patch 8.2.2455
Problem:    Vim9: key type that can be used for literal dict and indexing is
            inconsistent.
Solution:   Allow using number and bool as key for a literal dict. (#7771)
Files:      runtime/doc/vim9.txt, src/dict.c, src/eval.c, src/vim9compile.c,
            src/testdir/test_vim9_expr.vim, src/testdir/test_vim9_builtin.vim,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.2454/runtime/doc/vim9.txt        2021-01-31 17:02:06.278490083 
+0100
--- runtime/doc/vim9.txt        2021-02-03 17:39:53.048542236 +0100
***************
*** 548,553 ****
--- 548,559 ----
  like in JavaScript: >
        var dict = {["key" .. nr]: value}
  
+ The key type can be string, number, bool or float.  Other types result in an
+ error.  A number can be given with and without the []: >
+       var dict = {123: 'without', [456]: 'with'}
+       echo dict
+       {'456': 'with', '123': 'without'}
+ 
  
  No :xit, :t, :append, :change or :insert ~
  
*** ../vim-8.2.2454/src/dict.c  2021-01-22 22:06:51.636529831 +0100
--- src/dict.c  2021-02-03 17:12:40.582241104 +0100
***************
*** 953,963 ****
        }
        if (evaluate)
        {
!           if (vim9script && check_for_string(&tvkey) == FAIL)
            {
!               clear_tv(&tvkey);
!               goto failret;
            }
            key = tv_get_string_buf_chk(&tvkey, buf);
            if (key == NULL)
            {
--- 953,965 ----
        }
        if (evaluate)
        {
! #ifdef FEAT_FLOAT
!           if (tvkey.v_type == VAR_FLOAT)
            {
!               tvkey.vval.v_string = typval_tostring(&tvkey, TRUE);
!               tvkey.v_type = VAR_STRING;
            }
+ #endif
            key = tv_get_string_buf_chk(&tvkey, buf);
            if (key == NULL)
            {
*** ../vim-8.2.2454/src/eval.c  2021-01-23 14:22:10.228667110 +0100
--- src/eval.c  2021-02-03 17:23:30.511919709 +0100
***************
*** 3849,3859 ****
            clear_tv(&var1);
            return FAIL;
        }
!       else if (evaluate && tv_get_string_chk(&var1) == NULL)
        {
!           // not a number or string
!           clear_tv(&var1);
!           return FAIL;
        }
  
        /*
--- 3849,3871 ----
            clear_tv(&var1);
            return FAIL;
        }
!       else if (evaluate)
        {
! #ifdef FEAT_FLOAT
!           // allow for indexing with float
!           if (vim9 && rettv->v_type == VAR_DICT
!                                                  && var1.v_type == VAR_FLOAT)
!           {
!               var1.vval.v_string = typval_tostring(&var1, TRUE);
!               var1.v_type = VAR_STRING;
!           }
! #endif
!           if (tv_get_string_chk(&var1) == NULL)
!           {
!               // not a number or string
!               clear_tv(&var1);
!               return FAIL;
!           }
        }
  
        /*
*** ../vim-8.2.2454/src/vim9compile.c   2021-02-01 20:14:44.566705066 +0100
--- src/vim9compile.c   2021-02-03 16:45:39.511757869 +0100
***************
*** 3145,3151 ****
  compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
  {
      garray_T  *instr = &cctx->ctx_instr;
-     garray_T  *stack = &cctx->ctx_type_stack;
      int               count = 0;
      dict_T    *d = dict_alloc();
      dictitem_T        *item;
--- 3145,3150 ----
***************
*** 3180,3195 ****
            if (compile_expr0(arg, cctx) == FAIL)
                return FAIL;
            isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
!           if (isn->isn_type == ISN_PUSHS)
!               key = isn->isn_arg.string;
!           else
            {
!               type_T *keytype = ((type_T **)stack->ga_data)
!                                                      [stack->ga_len - 1];
!               if (need_type(keytype, &t_string, -1, 0, cctx,
!                                                    FALSE, FALSE) == FAIL)
!                   return FAIL;
            }
            *arg = skipwhite(*arg);
            if (**arg != ']')
            {
--- 3179,3197 ----
            if (compile_expr0(arg, cctx) == FAIL)
                return FAIL;
            isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
!           if (isn->isn_type == ISN_PUSHNR)
            {
!               char buf[NUMBUFLEN];
! 
!               // Convert to string at compile time.
!               vim_snprintf(buf, NUMBUFLEN, "%lld", isn->isn_arg.number);
!               isn->isn_type = ISN_PUSHS;
!               isn->isn_arg.string = vim_strsave((char_u *)buf);
            }
+           if (isn->isn_type == ISN_PUSHS)
+               key = isn->isn_arg.string;
+           else if (may_generate_2STRING(-1, cctx) == FAIL)
+               return FAIL;
            *arg = skipwhite(*arg);
            if (**arg != ']')
            {
*** ../vim-8.2.2454/src/testdir/test_vim9_expr.vim      2021-01-31 
21:47:39.036783041 +0100
--- src/testdir/test_vim9_expr.vim      2021-02-03 17:26:13.023355333 +0100
***************
*** 1354,1366 ****
    endfor
  
    # concatenating two lists with different member types results in "any"
!   var lines =<< trim END
!       var d = {}
!       for i in ['a'] + [0]
!         d = {[i]: 0}
!       endfor
!   END
!   CheckDefExecFailure(lines, 'E1012:')
  enddef
  
  " test multiply, divide, modulo
--- 1354,1364 ----
    endfor
  
    # concatenating two lists with different member types results in "any"
!   var dany = {}
!   for i in ['a'] + [12]
!     dany[i] = i
!   endfor
!   assert_equal({a: 'a', 12: 12}, dany)
  enddef
  
  " test multiply, divide, modulo
***************
*** 2116,2121 ****
--- 2114,2138 ----
        var cd = { # comment
                  key: 'val' # comment
                 }
+ 
+       # different types used for the key
+       var dkeys = {['key']: 'string',
+                    [12]: 'numberexpr',
+                    34: 'number',
+                    [true]: 'bool'} 
+       assert_equal('string', dkeys['key'])
+       assert_equal('numberexpr', dkeys[12])
+       assert_equal('number', dkeys[34])
+       assert_equal('bool', dkeys[true])
+       if has('float')
+         dkeys = {[1.2]: 'floatexpr', [3.4]: 'float'}
+         assert_equal('floatexpr', dkeys[1.2])
+         assert_equal('float', dkeys[3.4])
+       endif
+ 
+       # automatic conversion from number to string
+       var n = 123
+       var dictnr = {[n]: 1}
    END
    CheckDefAndScriptSuccess(lines)
   
***************
*** 2142,2157 ****
    CheckDefExecFailure(['var x: dict<string> = {a: 234, b: "1"}'], 'E1012:', 1)
    CheckDefExecFailure(['var x: dict<string> = {a: "x", b: 134}'], 'E1012:', 1)
  
    CheckDefFailure(['var x = ({'], 'E723:', 2)
    CheckDefExecFailure(['{}[getftype("file")]'], 'E716: Key not present in 
Dictionary: ""', 1)
- 
-   # no automatic conversion from number to string
-   lines =<< trim END
-       var n = 123
-       var d = {[n]: 1}
-   END
-   CheckDefFailure(lines, 'E1012:', 2)
-   CheckScriptFailure(['vim9script'] + lines, 'E928:', 3)
  enddef
  
  def Test_expr7_dict_vim9script()
--- 2159,2169 ----
    CheckDefExecFailure(['var x: dict<string> = {a: 234, b: "1"}'], 'E1012:', 1)
    CheckDefExecFailure(['var x: dict<string> = {a: "x", b: 134}'], 'E1012:', 1)
  
+   # invalid types for the key
+   CheckDefFailure(["var x = {[[1, 2]]: 0}"], 'E1105:', 1)
+ 
    CheckDefFailure(['var x = ({'], 'E723:', 2)
    CheckDefExecFailure(['{}[getftype("file")]'], 'E716: Key not present in 
Dictionary: ""', 1)
  enddef
  
  def Test_expr7_dict_vim9script()
*** ../vim-8.2.2454/src/testdir/test_vim9_builtin.vim   2021-02-01 
20:14:44.566705066 +0100
--- src/testdir/test_vim9_builtin.vim   2021-02-03 17:32:01.046156845 +0100
***************
*** 350,359 ****
    endif
  enddef
  
- def Wrong_dict_key_type(items: list<number>): list<number>
-   return filter(items, (_, val) => get({[val]: 1}, 'x'))
- enddef
- 
  def Test_filereadable()
    assert_false(filereadable(""))
    assert_false(filereadable(test_null_string()))
--- 350,355 ----
***************
*** 410,417 ****
    CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E928:')
  enddef
  
  def Test_filter_wrong_dict_key_type()
!   assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
  enddef
  
  def Test_filter_return_type()
--- 406,417 ----
    CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E928:')
  enddef
  
+ def Wrong_dict_key_type(items: list<number>): list<number>
+   return filter(items, (_, val) => get({[val]: 1}, 'x'))
+ enddef
+ 
  def Test_filter_wrong_dict_key_type()
!   assert_fails('Wrong_dict_key_type([1, v:null, 3])', 'E1013:')
  enddef
  
  def Test_filter_return_type()
*** ../vim-8.2.2454/src/testdir/test_vim9_script.vim    2021-01-31 
14:04:04.082702516 +0100
--- src/testdir/test_vim9_script.vim    2021-02-03 17:34:55.621558824 +0100
***************
*** 450,457 ****
  
    var nd: dict<any>
    try
!     nd = {[g:anumber]: 1}
!   catch /E1012:/
      n = 266
    endtry
    assert_equal(266, n)
--- 450,457 ----
  
    var nd: dict<any>
    try
!     nd = {[g:alist]: 1}
!   catch /E1105:/
      n = 266
    endtry
    assert_equal(266, n)
*** ../vim-8.2.2454/src/version.c       2021-02-03 15:58:09.088690884 +0100
--- src/version.c       2021-02-03 16:34:41.582027061 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2455,
  /**/

-- 
E  M  A  C  S
s  e  l  o  h
c  t  t  n  i
a  a     t  f
p        r  t
e        o
         l

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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/202102031641.113GfsVY1812749%40masaka.moolenaar.net.

Raspunde prin e-mail lui