diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-08-07 16:30:42 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-08-07 16:30:42 +0200 |
commit | 4270d8b7626ff8a7006f6a09c89bc446a3f89d1e (patch) | |
tree | c8b632c8862523490938e53418440ac393b46788 | |
parent | fbeefb1b87b0d52a095c08fee47b62d290bf4c33 (diff) | |
download | vim-git-4270d8b7626ff8a7006f6a09c89bc446a3f89d1e.tar.gz |
patch 8.2.3310: Vim9: unpack assignment does not mention source of type errorv8.2.3310
Problem: Vim9: unpack assignment does not mention source of type error.
Solution: Mention the argument number. (closes #8719)
-rw-r--r-- | src/testdir/test_vim9_assign.vim | 16 | ||||
-rw-r--r-- | src/testdir/test_vim9_disassemble.vim | 4 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 37 |
4 files changed, 47 insertions, 12 deletions
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 8491a4d87..a96e97cad 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -414,6 +414,22 @@ def Test_assign_unpack() [x, y] = g:values END CheckDefExecAndScriptFailure(lines, 'E1163: Variable 2: type mismatch, expected string but got number') + + lines =<< trim END + var x: number + var y: number + var z: string + [x, y, z] = [1, 2, 3] + END + CheckDefAndScriptFailure(lines, 'E1163: Variable 3: type mismatch, expected string but got number') + + lines =<< trim END + var x: number + var y: string + var z: string + [x, y, z] = [1, '2', 3] + END + CheckDefExecAndScriptFailure(lines, 'E1163: Variable 3: type mismatch, expected string but got number') enddef def Test_assign_linebreak() diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 253fe1b06..9eaa8647f 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -441,10 +441,10 @@ def Test_disassemble_list_assign() '\d CHECKTYPE list<any> stack\[-1\]\_s*' .. '\d CHECKLEN >= 2\_s*' .. '\d\+ ITEM 0\_s*' .. - '\d\+ CHECKTYPE string stack\[-1\]\_s*' .. + '\d\+ CHECKTYPE string stack\[-1\] arg 1\_s*' .. '\d\+ STORE $0\_s*' .. '\d\+ ITEM 1\_s*' .. - '\d\+ CHECKTYPE string stack\[-1\]\_s*' .. + '\d\+ CHECKTYPE string stack\[-1\] arg 2\_s*' .. '\d\+ STORE $1\_s*' .. '\d\+ SLICE 2\_s*' .. '\d\+ STORE $2\_s*' .. diff --git a/src/version.c b/src/version.c index 97823dfd8..9c374b164 100644 --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3310, +/**/ 3309, /**/ 3308, diff --git a/src/vim9compile.c b/src/vim9compile.c index 5d625e0c7..125135ada 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1039,18 +1039,16 @@ use_typecheck(type_T *actual, type_T *expected) * If "actual_is_const" is TRUE then the type won't change at runtime, do not * generate a TYPECHECK. */ - int -need_type( + static int +need_type_where( type_T *actual, type_T *expected, int offset, - int arg_idx, + where_T where, cctx_T *cctx, int silent, int actual_is_const) { - where_T where = WHERE_INIT; - if (expected == &t_bool && actual != &t_bool && (actual->tt_flags & TTFLAG_BOOL_OK)) { @@ -1060,7 +1058,6 @@ need_type( return OK; } - where.wt_index = arg_idx; if (check_type(expected, actual, FALSE, where) == OK) return OK; @@ -1069,15 +1066,32 @@ need_type( if ((!actual_is_const || actual == &t_any) && use_typecheck(actual, expected)) { - generate_TYPECHECK(cctx, expected, offset, arg_idx); + generate_TYPECHECK(cctx, expected, offset, where.wt_index); return OK; } if (!silent) - arg_type_mismatch(expected, actual, arg_idx); + type_mismatch_where(expected, actual, where); return FAIL; } + int +need_type( + type_T *actual, + type_T *expected, + int offset, + int arg_idx, + cctx_T *cctx, + int silent, + int actual_is_const) +{ + where_T where = WHERE_INIT; + + where.wt_index = arg_idx; + return need_type_where(actual, expected, offset, where, + cctx, silent, actual_is_const); +} + /* * Check that the top of the type stack has a type that can be used as a * condition. Give an error and return FAIL if not. @@ -7004,14 +7018,17 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) else if (*op == '=') { type_T *use_type = lhs.lhs_lvar->lv_type; + where_T where = WHERE_INIT; // Without operator check type here, otherwise below. // Use the line number of the assignment. SOURCING_LNUM = start_lnum; + where.wt_index = var_count > 0 ? var_idx + 1 : 0; + where.wt_variable = var_count > 0; if (lhs.lhs_has_index) use_type = lhs.lhs_member_type; - if (need_type(rhs_type, use_type, -1, 0, cctx, - FALSE, is_const) == FAIL) + if (need_type_where(rhs_type, use_type, -1, where, + cctx, FALSE, is_const) == FAIL) goto theend; } } |