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);
|
clear_tv(&tvkey);
|
||||||
goto failret;
|
goto failret;
|
||||||
}
|
}
|
||||||
|
if (check_typval_is_value(&tv) == FAIL)
|
||||||
|
{
|
||||||
|
if (evaluate)
|
||||||
|
{
|
||||||
|
clear_tv(&tvkey);
|
||||||
|
clear_tv(&tv);
|
||||||
|
}
|
||||||
|
goto failret;
|
||||||
|
}
|
||||||
if (evaluate)
|
if (evaluate)
|
||||||
{
|
{
|
||||||
item = dict_find(d, key, -1);
|
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!
|
if (eval1(arg, &tv, evalarg) == FAIL) // recursive!
|
||||||
goto failret;
|
goto failret;
|
||||||
|
if (check_typval_is_value(&tv) == FAIL)
|
||||||
|
{
|
||||||
|
if (evaluate)
|
||||||
|
clear_tv(&tv);
|
||||||
|
goto failret;
|
||||||
|
}
|
||||||
if (evaluate)
|
if (evaluate)
|
||||||
{
|
{
|
||||||
item = listitem_alloc();
|
item = listitem_alloc();
|
||||||
|
@@ -3361,4 +3361,94 @@ def Test_assign_to_any()
|
|||||||
endfor
|
endfor
|
||||||
enddef
|
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
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
@@ -190,7 +190,7 @@ def Test_class_basic()
|
|||||||
endclass
|
endclass
|
||||||
sort([1.1, A], 'f')
|
sort([1.1, A], 'f')
|
||||||
END
|
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
|
# Test for using object as a float
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
|
@@ -277,7 +277,7 @@ def Test_typealias()
|
|||||||
type B = number
|
type B = number
|
||||||
sort([1.1, B], 'f')
|
sort([1.1, B], 'f')
|
||||||
END
|
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
|
# Creating a typealias in a def function
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2163,
|
||||||
/**/
|
/**/
|
||||||
2162,
|
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
|
// Get the member type and the declared member type from all the items on
|
||||||
// the stack.
|
// 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);
|
type = get_list_type(member_type, cctx->ctx_type_list);
|
||||||
decl_type = get_list_type(&t_any, 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;
|
return FAIL;
|
||||||
isn->isn_arg.number = use_null ? -1 : count;
|
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);
|
type = get_dict_type(member_type, cctx->ctx_type_list);
|
||||||
decl_type = get_dict_type(&t_any, 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.
|
// Use "unknown" for an empty list or dict.
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return &t_unknown;
|
return &t_unknown;
|
||||||
|
// Find the common type from following items.
|
||||||
// Use the first value type for the list member type, then find the common
|
|
||||||
// type from following items.
|
|
||||||
typep = ((type2_T *)stack->ga_data) + stack->ga_len;
|
typep = ((type2_T *)stack->ga_data) + stack->ga_len;
|
||||||
result = (typep -(count * skip) + skip - 1)->type_curr;
|
result = &t_unknown;
|
||||||
for (i = 1; i < count; ++i)
|
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;
|
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);
|
common_type(type, result, &result, type_gap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user