diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-11-30 16:14:49 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-11-30 16:14:49 +0000 |
commit | ab36e6ae7b87b0295fb19270e4339a734875c6b1 (patch) | |
tree | f049630a28f6c7967eafd5220f43a7ff23b79123 /src | |
parent | 53ba95e4f0a82f6dab1791bb01f6cddc9b3f61b3 (diff) | |
download | vim-git-ab36e6ae7b87b0295fb19270e4339a734875c6b1.tar.gz |
patch 8.2.3704: Vim9: cannot use a list declaration in a :def functionv8.2.3704
Problem: Vim9: cannot use a list declaration in a :def function.
Solution: Make it work.
Diffstat (limited to 'src')
-rw-r--r-- | src/errors.h | 3 | ||||
-rw-r--r-- | src/testdir/test_vim9_assign.vim | 55 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 14 |
4 files changed, 62 insertions, 12 deletions
diff --git a/src/errors.h b/src/errors.h index 5cc98e786..e09ef53dc 100644 --- a/src/errors.h +++ b/src/errors.h @@ -366,8 +366,7 @@ EXTERN char e_cannot_assign_to_argument[] INIT(= N_("E1090: Cannot assign to argument %s")); EXTERN char e_function_is_not_compiled_str[] INIT(= N_("E1091: Function is not compiled: %s")); -EXTERN char e_cannot_use_list_for_declaration[] - INIT(= N_("E1092: Cannot use a list for a declaration")); +// E1092 unused EXTERN char e_expected_nr_items_but_got_nr[] INIT(= N_("E1093: Expected %d items but got %d")); EXTERN char e_import_can_only_be_used_in_script[] diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 394dfe663..87924c629 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -732,7 +732,6 @@ def Test_assignment_list() assert_equal(['sdf', 'asdf', 'end'], list3) CheckDefExecFailure(['var ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:') - CheckDefExecFailure(['var [v1, v2] = [1, 2]'], 'E1092:') # type becomes list<any> var somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c'] @@ -753,6 +752,60 @@ def Test_assignment_list() CheckDefExecAndScriptFailure(lines, 'E1012:', 5) enddef +def Test_list_declaration() + var [v1, v2] = [1, 2] + v1 += 3 + assert_equal(4, v1) + v2 *= 3 + assert_equal(6, v2) + + var lines =<< trim END + var [v1, v2] = [1] + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 1', 'E688:') + lines =<< trim END + var testlist = [1] + var [v1, v2] = testlist + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 1', 'E688:') + lines =<< trim END + var [v1, v2] = [1, 2, 3] + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 3', 'E687:') + lines =<< trim END + var testlist = [1, 2, 3] + var [v1, v2] = testlist + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 3', 'E687:') + + var [vnr, vstr] = [123, 'text'] + vnr += 3 + assert_equal(126, vnr) + vstr ..= 'end' + assert_equal('textend', vstr) + + var [vnr2: number, vstr2: string] = [123, 'text'] + vnr2 += 3 + assert_equal(126, vnr2) + vstr2 ..= 'end' + assert_equal('textend', vstr2) + + var [vnr3: number; vlist: list<string>] = [123, 'foo', 'bar'] + vnr3 += 5 + assert_equal(128, vnr3) + assert_equal(['foo', 'bar'], vlist) + + lines =<< trim END + var [vnr2: number, vstr2: number] = [123, 'text'] + END + CheckDefExecAndScriptFailure2(lines, 'E1163: Variable 2: type mismatch, expected number but got string', 'E1012: Type mismatch; expected number but got string') + lines =<< trim END + var testlist = [234, 'text'] + var [vnr2: number, vstr2: number] = testlist + END + CheckDefExecAndScriptFailure2(lines, 'E1163: Variable 2: type mismatch, expected number but got string', 'E1012: Type mismatch; expected number but got string') +enddef + def PartFuncBool(b: bool): string return 'done' enddef diff --git a/src/version.c b/src/version.c index a190af5c9..32efc5c83 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3704, +/**/ 3703, /**/ 3702, diff --git a/src/vim9compile.c b/src/vim9compile.c index e5e806cb6..58149ed5c 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -144,6 +144,7 @@ typedef struct { // any "[expr]" or ".name" char_u *lhs_dest_end; // end of the destination, including // "[expr]" or ".name". + char_u *lhs_end; // end including any type int lhs_has_index; // has "[expr]" or ".name" @@ -6299,6 +6300,7 @@ compile_lhs( --lhs->lhs_dest_end; if (is_decl && var_end == var_start + 2 && var_end[-1] == ':') --var_end; + lhs->lhs_end = lhs->lhs_dest_end; // compute the length of the destination without "[expr]" or ".name" lhs->lhs_varlen = var_end - var_start; @@ -6435,7 +6437,7 @@ compile_lhs( } } - // handle "a:name" as a name, not index "name" on "a" + // handle "a:name" as a name, not index "name" in "a" if (lhs->lhs_varlen > 1 || var_start[lhs->lhs_varlen] != ':') var_end = lhs->lhs_dest_end; @@ -6456,6 +6458,7 @@ compile_lhs( if (lhs->lhs_type == NULL) return FAIL; lhs->lhs_has_type = TRUE; + lhs->lhs_end = p; } else if (lhs->lhs_lvar != NULL) lhs->lhs_type = lhs->lhs_lvar->lv_type; @@ -6896,13 +6899,6 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) if (p == NULL) return *arg == '[' ? arg : NULL; - if (var_count > 0 && is_decl) - { - // TODO: should we allow this, and figure out type inference from list - // members? - emsg(_(e_cannot_use_list_for_declaration)); - return NULL; - } lhs.lhs_name = NULL; sp = p; @@ -7330,7 +7326,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) cctx->ctx_lnum = save_lnum; if (var_idx + 1 < var_count) - var_start = skipwhite(lhs.lhs_dest_end + 1); + var_start = skipwhite(lhs.lhs_end + 1); } // For "[var, var] = expr" drop the "expr" value. |