mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.0.2163: Vim9: type can be assigned to list/dict
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>
This commit is contained in:
committed by
Christian Brabandt
parent
2a71b54d35
commit
fa831102c3
@@ -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);
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2163,
|
||||
/**/
|
||||
2162,
|
||||
/**/
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -1660,16 +1660,15 @@ 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;
|
||||
if (check_type_is_value(type) == FAIL)
|
||||
return NULL;
|
||||
if (result != &t_any)
|
||||
common_type(type, result, &result, type_gap);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user