diff options
author | Ernie Rael <errael@raelity.com> | 2023-12-14 20:06:39 +0100 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2023-12-14 20:06:39 +0100 |
commit | fa831102c38c9192edf3aaf0cbcaff9ee5e006ac (patch) | |
tree | 6643f2b8d5784dd0b9571fe9a53590a2102524a5 | |
parent | 2a71b54d35361f3f0c24db88c672b426f8acc7b7 (diff) |
patch 9.0.2163: Vim9: type can be assigned to list/dictv9.0.2163
Problem: Vim9: type can be assigned to list/dict
Solution: Prevent assigning a `type` to a `list` or `dict`
closes: #13683
Signed-off-by: Ernie Rael <errael@raelity.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r-- | src/dict.c | 9 | ||||
-rw-r--r-- | src/list.c | 6 | ||||
-rw-r--r-- | src/testdir/test_vim9_assign.vim | 90 | ||||
-rw-r--r-- | src/testdir/test_vim9_class.vim | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_typealias.vim | 2 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9instr.c | 6 | ||||
-rw-r--r-- | src/vim9type.c | 15 |
8 files changed, 120 insertions, 12 deletions
diff --git a/src/dict.c b/src/dict.c index ce807350cd..cb22b42c91 100644 --- a/src/dict.c +++ b/src/dict.c @@ -1015,6 +1015,15 @@ eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal) clear_tv(&tvkey); goto failret; } + if (check_typval_is_value(&tv) == FAIL) + { + if (evaluate) + { + clear_tv(&tvkey); + clear_tv(&tv); + } + goto failret; + } if (evaluate) { item = dict_find(d, key, -1); diff --git a/src/list.c b/src/list.c index ce1ccaa1c0..b50cb03c98 100644 --- a/src/list.c +++ b/src/list.c @@ -1576,6 +1576,12 @@ eval_list(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int do_error) { if (eval1(arg, &tv, evalarg) == FAIL) // recursive! goto failret; + if (check_typval_is_value(&tv) == FAIL) + { + if (evaluate) + clear_tv(&tv); + goto failret; + } if (evaluate) { item = listitem_alloc(); diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index e288d0306e..38504f1af9 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -3361,4 +3361,94 @@ def Test_assign_to_any() endfor enddef +def Test_assign_type_to_list_dict() + var lines =<< trim END + vim9script + class C + endclass + + var x = [C] + END + v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + + lines =<< trim END + vim9script + class C + endclass + type T = C + + def F() + var x = [3, T, C] + enddef + F() + END + v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + + lines =<< trim END + vim9script + type T = number + + def F() + var x = [3, T] + enddef + F() + END + v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value') + + lines =<< trim END + vim9script + class C + endclass + + var x = {e: C} + END + v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + + lines =<< trim END + vim9script + class C + endclass + + def F() + var x = {e: C} + enddef + F() + END + v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + + lines =<< trim END + vim9script + type T = number + + def F() + var x = {e: T} + enddef + F() + END + v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value') + + lines =<< trim END + vim9script + class C + endclass + + def F() + var x = {e: [C]} + enddef + F() + END + v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + + lines =<< trim END + vim9script + type T = number + + def F() + var x = {e: [T]} + enddef + F() + END + v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value') +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index c1965880cf..5a9b0f8884 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -190,7 +190,7 @@ def Test_class_basic() endclass sort([1.1, A], 'f') END - v9.CheckSourceFailure(lines, 'E1321: Using a Class as a Float', 4) + v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4) # Test for using object as a float lines =<< trim END diff --git a/src/testdir/test_vim9_typealias.vim b/src/testdir/test_vim9_typealias.vim index 20829340f2..11aa47aa63 100644 --- a/src/testdir/test_vim9_typealias.vim +++ b/src/testdir/test_vim9_typealias.vim @@ -277,7 +277,7 @@ def Test_typealias() type B = number sort([1.1, B], 'f') END - v9.CheckSourceFailure(lines, 'E1401: Using type alias "B" as a Float', 3) + v9.CheckSourceFailure(lines, 'E1403: Type alias "B" cannot be used as a value', 3) # Creating a typealias in a def function lines =<< trim END diff --git a/src/version.c b/src/version.c index 6813d54110..a4b4edfdc2 100644 --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2163, +/**/ 2162, /**/ 2161, diff --git a/src/vim9instr.c b/src/vim9instr.c index 3547d42f4a..12c83df9b8 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -1333,7 +1333,8 @@ generate_NEWLIST(cctx_T *cctx, int count, int use_null) // Get the member type and the declared member type from all the items on // the stack. - member_type = get_member_type_from_stack(count, 1, cctx); + if ((member_type = get_member_type_from_stack(count, 1, cctx)) == NULL) + return FAIL; type = get_list_type(member_type, cctx->ctx_type_list); decl_type = get_list_type(&t_any, cctx->ctx_type_list); @@ -1361,7 +1362,8 @@ generate_NEWDICT(cctx_T *cctx, int count, int use_null) return FAIL; isn->isn_arg.number = use_null ? -1 : count; - member_type = get_member_type_from_stack(count, 2, cctx); + if ((member_type = get_member_type_from_stack(count, 2, cctx)) == NULL) + return FAIL; type = get_dict_type(member_type, cctx->ctx_type_list); decl_type = get_dict_type(&t_any, cctx->ctx_type_list); diff --git a/src/vim9type.c b/src/vim9type.c index fec2bf9d3e..8840c37ccc 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -1660,17 +1660,16 @@ get_member_type_from_stack( // Use "unknown" for an empty list or dict. if (count == 0) return &t_unknown; - - // Use the first value type for the list member type, then find the common - // type from following items. + // Find the common type from following items. typep = ((type2_T *)stack->ga_data) + stack->ga_len; - result = (typep -(count * skip) + skip - 1)->type_curr; - for (i = 1; i < count; ++i) + result = &t_unknown; + for (i = 0; i < count; ++i) { - if (result == &t_any) - break; // won't get more common type = (typep -((count - i) * skip) + skip - 1)->type_curr; - common_type(type, result, &result, type_gap); + if (check_type_is_value(type) == FAIL) + return NULL; + if (result != &t_any) + common_type(type, result, &result, type_gap); } return result; |