summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-01-10 19:23:27 +0100
committerBram Moolenaar <Bram@vim.org>2021-01-10 19:23:27 +0100
commit31a11b942a56bf75a653eec0976f365f9b389a5a (patch)
treeded767365312f9bd28ef860a682ee0feac4be53e
parent0186e58639b19933d3d9188d552fe6745265eb1b (diff)
downloadvim-git-31a11b942a56bf75a653eec0976f365f9b389a5a.tar.gz
patch 8.2.2323: Vim9: error when inferring type from empty dict/listv8.2.2323
Problem: Vim9: error when inferring type from empty dict/list. Solution: When the member is t_unknown use t_any. (closes #7009)
-rw-r--r--src/testdir/test_vim9_expr.vim19
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c15
3 files changed, 35 insertions, 1 deletions
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index fc42088d8..8955a7ccf 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -2929,6 +2929,16 @@ def Test_expr7_list_subscript()
lines = ['var l = [0, 1, 2]', 'echo l[g:astring : g:theone]']
CheckDefExecFailure(lines, 'E1012:')
CheckScriptFailure(['vim9script'] + lines, 'E1030:', 3)
+
+ lines =<< trim END
+ vim9script
+ var ld = []
+ def Func()
+ eval ld[0].key
+ enddef
+ defcompile
+ END
+ CheckScriptSuccess(lines)
enddef
def Test_expr7_dict_subscript()
@@ -2937,6 +2947,15 @@ def Test_expr7_dict_subscript()
var l = [{lnum: 2}, {lnum: 1}]
var res = l[0].lnum > l[1].lnum
assert_true(res)
+
+ var dd = {}
+ def Func1()
+ eval dd.key1.key2
+ enddef
+ def Func2()
+ eval dd['key1'].key2
+ enddef
+ defcompile
END
CheckScriptSuccess(lines)
enddef
diff --git a/src/version.c b/src/version.c
index cdf27fac7..a21122aa6 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2323,
+/**/
2322,
/**/
2321,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index a6bb56571..94f30d439 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1899,7 +1899,10 @@ generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len)
}
// change dict type to dict member type
if (type->tt_type == VAR_DICT)
- ((type_T **)stack->ga_data)[stack->ga_len - 1] = type->tt_member;
+ {
+ ((type_T **)stack->ga_data)[stack->ga_len - 1] =
+ type->tt_member == &t_unknown ? &t_any : type->tt_member;
+ }
return OK;
}
@@ -3793,7 +3796,12 @@ compile_subscript(
return FAIL;
}
if ((*typep)->tt_type == VAR_DICT)
+ {
*typep = (*typep)->tt_member;
+ if (*typep == &t_unknown)
+ // empty dict was used
+ *typep = &t_any;
+ }
else
{
if (need_type(*typep, &t_dict_any, -2, cctx,
@@ -3831,7 +3839,12 @@ compile_subscript(
else
{
if ((*typep)->tt_type == VAR_LIST)
+ {
*typep = (*typep)->tt_member;
+ if (*typep == &t_unknown)
+ // empty list was used
+ *typep = &t_any;
+ }
if (generate_instr_drop(cctx,
vtype == VAR_LIST ? ISN_LISTINDEX : ISN_ANYINDEX,
1) == FAIL)