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.