forked from aniani/vim
patch 8.2.3866: Vim9: type checking global variables is inconsistent
Problem: Vim9: type checking global variables is inconsistent. Solution: Use the "unknown" type in more places.
This commit is contained in:
@@ -228,7 +228,9 @@ check_arg_type(
|
|||||||
arg_float_or_nr(type_T *type, argcontext_T *context)
|
arg_float_or_nr(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_FLOAT || type->tt_type == VAR_NUMBER)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_FLOAT
|
||||||
|
|| type->tt_type == VAR_NUMBER)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_number, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_number, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -313,7 +315,9 @@ arg_bool(type_T *type, argcontext_T *context)
|
|||||||
arg_list_or_blob(type_T *type, argcontext_T *context)
|
arg_list_or_blob(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_LIST || type->tt_type == VAR_BLOB)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_LIST
|
||||||
|
|| type->tt_type == VAR_BLOB)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -326,7 +330,9 @@ arg_list_or_blob(type_T *type, argcontext_T *context)
|
|||||||
arg_string_or_nr(type_T *type, argcontext_T *context)
|
arg_string_or_nr(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_STRING
|
||||||
|
|| type->tt_type == VAR_NUMBER)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -339,7 +345,9 @@ arg_string_or_nr(type_T *type, argcontext_T *context)
|
|||||||
arg_buffer(type_T *type, argcontext_T *context)
|
arg_buffer(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_STRING
|
||||||
|
|| type->tt_type == VAR_NUMBER)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -352,6 +360,7 @@ arg_buffer(type_T *type, argcontext_T *context)
|
|||||||
arg_buffer_or_dict_any(type_T *type, argcontext_T *context)
|
arg_buffer_or_dict_any(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_STRING
|
|| type->tt_type == VAR_STRING
|
||||||
|| type->tt_type == VAR_NUMBER
|
|| type->tt_type == VAR_NUMBER
|
||||||
|| type->tt_type == VAR_DICT)
|
|| type->tt_type == VAR_DICT)
|
||||||
@@ -367,7 +376,9 @@ arg_buffer_or_dict_any(type_T *type, argcontext_T *context)
|
|||||||
arg_lnum(type_T *type, argcontext_T *context)
|
arg_lnum(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_STRING
|
||||||
|
|| type->tt_type == VAR_NUMBER)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -379,7 +390,9 @@ arg_lnum(type_T *type, argcontext_T *context)
|
|||||||
static int
|
static int
|
||||||
arg_string_or_list_string(type_T *type, argcontext_T *context)
|
arg_string_or_list_string(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY || type->tt_type == VAR_STRING)
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_STRING)
|
||||||
return OK;
|
return OK;
|
||||||
if (type->tt_type != VAR_LIST)
|
if (type->tt_type != VAR_LIST)
|
||||||
{
|
{
|
||||||
@@ -401,7 +414,9 @@ arg_string_or_list_string(type_T *type, argcontext_T *context)
|
|||||||
arg_string_or_list_any(type_T *type, argcontext_T *context)
|
arg_string_or_list_any(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_STRING || type->tt_type == VAR_LIST)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_STRING
|
||||||
|
|| type->tt_type == VAR_LIST)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -414,7 +429,9 @@ arg_string_or_list_any(type_T *type, argcontext_T *context)
|
|||||||
arg_string_or_blob(type_T *type, argcontext_T *context)
|
arg_string_or_blob(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_STRING || type->tt_type == VAR_BLOB)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_STRING
|
||||||
|
|| type->tt_type == VAR_BLOB)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -427,7 +444,9 @@ arg_string_or_blob(type_T *type, argcontext_T *context)
|
|||||||
arg_list_or_dict(type_T *type, argcontext_T *context)
|
arg_list_or_dict(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|| type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|
|| type->tt_type == VAR_LIST
|
||||||
|
|| type->tt_type == VAR_DICT)
|
||||||
return OK;
|
return OK;
|
||||||
arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
|
arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -440,6 +459,7 @@ arg_list_or_dict(type_T *type, argcontext_T *context)
|
|||||||
arg_list_or_dict_or_blob(type_T *type, argcontext_T *context)
|
arg_list_or_dict_or_blob(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_LIST
|
|| type->tt_type == VAR_LIST
|
||||||
|| type->tt_type == VAR_DICT
|
|| type->tt_type == VAR_DICT
|
||||||
|| type->tt_type == VAR_BLOB)
|
|| type->tt_type == VAR_BLOB)
|
||||||
@@ -455,6 +475,7 @@ arg_list_or_dict_or_blob(type_T *type, argcontext_T *context)
|
|||||||
arg_list_or_dict_or_blob_or_string(type_T *type, argcontext_T *context)
|
arg_list_or_dict_or_blob_or_string(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_LIST
|
|| type->tt_type == VAR_LIST
|
||||||
|| type->tt_type == VAR_DICT
|
|| type->tt_type == VAR_DICT
|
||||||
|| type->tt_type == VAR_BLOB
|
|| type->tt_type == VAR_BLOB
|
||||||
@@ -471,6 +492,7 @@ arg_list_or_dict_or_blob_or_string(type_T *type, argcontext_T *context)
|
|||||||
arg_string_list_or_blob(type_T *type, argcontext_T *context)
|
arg_string_list_or_blob(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_LIST
|
|| type->tt_type == VAR_LIST
|
||||||
|| type->tt_type == VAR_BLOB
|
|| type->tt_type == VAR_BLOB
|
||||||
|| type->tt_type == VAR_STRING)
|
|| type->tt_type == VAR_STRING)
|
||||||
@@ -495,6 +517,7 @@ arg_job(type_T *type, argcontext_T *context)
|
|||||||
arg_chan_or_job(type_T *type, argcontext_T *context)
|
arg_chan_or_job(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_CHANNEL
|
|| type->tt_type == VAR_CHANNEL
|
||||||
|| type->tt_type == VAR_JOB)
|
|| type->tt_type == VAR_JOB)
|
||||||
return OK;
|
return OK;
|
||||||
@@ -557,6 +580,7 @@ arg_item_of_prev(type_T *type, argcontext_T *context)
|
|||||||
arg_str_or_nr_or_list(type_T *type, argcontext_T *context)
|
arg_str_or_nr_or_list(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_STRING
|
|| type->tt_type == VAR_STRING
|
||||||
|| type->tt_type == VAR_NUMBER
|
|| type->tt_type == VAR_NUMBER
|
||||||
|| type->tt_type == VAR_LIST)
|
|| type->tt_type == VAR_LIST)
|
||||||
@@ -572,6 +596,7 @@ arg_str_or_nr_or_list(type_T *type, argcontext_T *context)
|
|||||||
arg_dict_any_or_string(type_T *type, argcontext_T *context)
|
arg_dict_any_or_string(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_DICT
|
|| type->tt_type == VAR_DICT
|
||||||
|| type->tt_type == VAR_STRING)
|
|| type->tt_type == VAR_STRING)
|
||||||
return OK;
|
return OK;
|
||||||
@@ -603,6 +628,7 @@ arg_extend3(type_T *type, argcontext_T *context)
|
|||||||
arg_get1(type_T *type, argcontext_T *context)
|
arg_get1(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_BLOB
|
|| type->tt_type == VAR_BLOB
|
||||||
|| type->tt_type == VAR_LIST
|
|| type->tt_type == VAR_LIST
|
||||||
|| type->tt_type == VAR_DICT
|
|| type->tt_type == VAR_DICT
|
||||||
@@ -622,6 +648,7 @@ arg_get1(type_T *type, argcontext_T *context)
|
|||||||
arg_len1(type_T *type, argcontext_T *context)
|
arg_len1(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_STRING
|
|| type->tt_type == VAR_STRING
|
||||||
|| type->tt_type == VAR_NUMBER
|
|| type->tt_type == VAR_NUMBER
|
||||||
|| type->tt_type == VAR_BLOB
|
|| type->tt_type == VAR_BLOB
|
||||||
@@ -657,6 +684,7 @@ arg_remove2(type_T *type, argcontext_T *context)
|
|||||||
arg_repeat1(type_T *type, argcontext_T *context)
|
arg_repeat1(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_STRING
|
|| type->tt_type == VAR_STRING
|
||||||
|| type->tt_type == VAR_NUMBER
|
|| type->tt_type == VAR_NUMBER
|
||||||
|| type->tt_type == VAR_LIST)
|
|| type->tt_type == VAR_LIST)
|
||||||
@@ -674,6 +702,7 @@ arg_repeat1(type_T *type, argcontext_T *context)
|
|||||||
arg_slice1(type_T *type, argcontext_T *context)
|
arg_slice1(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_LIST
|
|| type->tt_type == VAR_LIST
|
||||||
|| type->tt_type == VAR_BLOB
|
|| type->tt_type == VAR_BLOB
|
||||||
|| type->tt_type == VAR_STRING)
|
|| type->tt_type == VAR_STRING)
|
||||||
@@ -691,6 +720,7 @@ arg_slice1(type_T *type, argcontext_T *context)
|
|||||||
arg_count1(type_T *type, argcontext_T *context)
|
arg_count1(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_STRING
|
|| type->tt_type == VAR_STRING
|
||||||
|| type->tt_type == VAR_LIST
|
|| type->tt_type == VAR_LIST
|
||||||
|| type->tt_type == VAR_DICT)
|
|| type->tt_type == VAR_DICT)
|
||||||
@@ -708,6 +738,7 @@ arg_count1(type_T *type, argcontext_T *context)
|
|||||||
arg_cursor1(type_T *type, argcontext_T *context)
|
arg_cursor1(type_T *type, argcontext_T *context)
|
||||||
{
|
{
|
||||||
if (type->tt_type == VAR_ANY
|
if (type->tt_type == VAR_ANY
|
||||||
|
|| type->tt_type == VAR_UNKNOWN
|
||||||
|| type->tt_type == VAR_NUMBER
|
|| type->tt_type == VAR_NUMBER
|
||||||
|| type->tt_type == VAR_STRING
|
|| type->tt_type == VAR_STRING
|
||||||
|| type->tt_type == VAR_LIST)
|
|| type->tt_type == VAR_LIST)
|
||||||
|
@@ -404,9 +404,16 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE);
|
|||||||
|
|
||||||
|
|
||||||
// Commonly used types.
|
// Commonly used types.
|
||||||
|
// "unknown" is used for when the type is really unknown, e.g. global
|
||||||
|
// variables. Also for when a function may or may not return something.
|
||||||
EXTERN type_T t_unknown INIT6(VAR_UNKNOWN, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
EXTERN type_T t_unknown INIT6(VAR_UNKNOWN, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
||||||
|
|
||||||
|
// "any" is used for when the type is mixed. Excludes "void".
|
||||||
EXTERN type_T t_any INIT6(VAR_ANY, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
EXTERN type_T t_any INIT6(VAR_ANY, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
||||||
|
|
||||||
|
// "void" is used for a function not returning anything.
|
||||||
EXTERN type_T t_void INIT6(VAR_VOID, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
EXTERN type_T t_void INIT6(VAR_VOID, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
||||||
|
|
||||||
EXTERN type_T t_bool INIT6(VAR_BOOL, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
EXTERN type_T t_bool INIT6(VAR_BOOL, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
||||||
EXTERN type_T t_special INIT6(VAR_SPECIAL, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
EXTERN type_T t_special INIT6(VAR_SPECIAL, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
||||||
EXTERN type_T t_number INIT6(VAR_NUMBER, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
EXTERN type_T t_number INIT6(VAR_NUMBER, 0, 0, TTFLAG_STATIC, NULL, NULL);
|
||||||
|
@@ -547,6 +547,39 @@ def Test_call_default_args()
|
|||||||
defcompile
|
defcompile
|
||||||
END
|
END
|
||||||
CheckScriptFailure(lines, 'E1001: Variable not found: b')
|
CheckScriptFailure(lines, 'E1001: Variable not found: b')
|
||||||
|
|
||||||
|
# using script variable requires matching type or type cast
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
var a: any
|
||||||
|
def Func(arg: string = a)
|
||||||
|
echo arg
|
||||||
|
enddef
|
||||||
|
defcompile
|
||||||
|
END
|
||||||
|
CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got any')
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
var a: any
|
||||||
|
def Func(arg: string = <string>a)
|
||||||
|
echo arg
|
||||||
|
enddef
|
||||||
|
a = 'works'
|
||||||
|
Func()
|
||||||
|
END
|
||||||
|
CheckScriptSuccess(lines)
|
||||||
|
|
||||||
|
# using global variable does not require type cast
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Func(arg: string = g:str)
|
||||||
|
echo arg
|
||||||
|
enddef
|
||||||
|
g:str = 'works'
|
||||||
|
Func()
|
||||||
|
END
|
||||||
|
CheckScriptSuccess(lines)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def FuncWithComment( # comment
|
def FuncWithComment( # comment
|
||||||
|
@@ -749,6 +749,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 */
|
||||||
|
/**/
|
||||||
|
3866,
|
||||||
/**/
|
/**/
|
||||||
3865,
|
3865,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -843,8 +843,11 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
// If we know the type of "var" and it is a not a supported type we can
|
// If we know the type of "var" and it is a not a supported type we can
|
||||||
// give an error now.
|
// give an error now.
|
||||||
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
if (vartype->tt_type != VAR_LIST && vartype->tt_type != VAR_STRING
|
if (vartype->tt_type != VAR_LIST
|
||||||
&& vartype->tt_type != VAR_BLOB && vartype->tt_type != VAR_ANY)
|
&& vartype->tt_type != VAR_STRING
|
||||||
|
&& vartype->tt_type != VAR_BLOB
|
||||||
|
&& vartype->tt_type != VAR_ANY
|
||||||
|
&& vartype->tt_type != VAR_UNKNOWN)
|
||||||
{
|
{
|
||||||
semsg(_(e_for_loop_on_str_not_supported),
|
semsg(_(e_for_loop_on_str_not_supported),
|
||||||
vartype_name(vartype->tt_type));
|
vartype_name(vartype->tt_type));
|
||||||
|
@@ -90,7 +90,7 @@ compile_member(int is_slice, int *keeping_dict, cctx_T *cctx)
|
|||||||
vartype = (*typep)->tt_type;
|
vartype = (*typep)->tt_type;
|
||||||
idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
// If the index is a string, the variable must be a Dict.
|
// If the index is a string, the variable must be a Dict.
|
||||||
if (*typep == &t_any && idxtype == &t_string)
|
if ((*typep == &t_any || *typep == &t_unknown) && idxtype == &t_string)
|
||||||
vartype = VAR_DICT;
|
vartype = VAR_DICT;
|
||||||
if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
|
if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
|
||||||
{
|
{
|
||||||
@@ -156,7 +156,7 @@ compile_member(int is_slice, int *keeping_dict, cctx_T *cctx)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (vartype == VAR_LIST || *typep == &t_any)
|
else if (vartype == VAR_LIST || *typep == &t_any || *typep == &t_unknown)
|
||||||
{
|
{
|
||||||
if (is_slice)
|
if (is_slice)
|
||||||
{
|
{
|
||||||
@@ -415,7 +415,7 @@ compile_load(
|
|||||||
// Global, Buffer-local, Window-local and Tabpage-local
|
// Global, Buffer-local, Window-local and Tabpage-local
|
||||||
// variables can be defined later, thus we don't check if it
|
// variables can be defined later, thus we don't check if it
|
||||||
// exists, give an error at runtime.
|
// exists, give an error at runtime.
|
||||||
res = generate_LOAD(cctx, isn_type, 0, name, &t_any);
|
res = generate_LOAD(cctx, isn_type, 0, name, &t_unknown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1428,7 +1428,10 @@ bool_on_stack(cctx_T *cctx)
|
|||||||
if (type == &t_bool)
|
if (type == &t_bool)
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
if (type == &t_any || type == &t_number || type == &t_number_bool)
|
if (type == &t_any
|
||||||
|
|| type == &t_unknown
|
||||||
|
|| type == &t_number
|
||||||
|
|| type == &t_number_bool)
|
||||||
// Number 0 and 1 are OK to use as a bool. "any" could also be a bool.
|
// Number 0 and 1 are OK to use as a bool. "any" could also be a bool.
|
||||||
// This requires a runtime type check.
|
// This requires a runtime type check.
|
||||||
return generate_COND2BOOL(cctx);
|
return generate_COND2BOOL(cctx);
|
||||||
@@ -2155,9 +2158,10 @@ compile_expr7t(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
|||||||
|
|
||||||
generate_ppconst(cctx, ppconst);
|
generate_ppconst(cctx, ppconst);
|
||||||
actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
if (check_type(want_type, actual, FALSE, where) == FAIL)
|
if (check_type_maybe(want_type, actual, FALSE, where) != OK)
|
||||||
{
|
{
|
||||||
if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
|
if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE)
|
||||||
|
== FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -168,9 +168,10 @@ may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
|
|||||||
static int
|
static int
|
||||||
check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
|
check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
|
||||||
{
|
{
|
||||||
if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_ANY)
|
if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT
|
||||||
|
|| type1 == VAR_ANY || type1 == VAR_UNKNOWN)
|
||||||
&& (type2 == VAR_NUMBER || type2 == VAR_FLOAT
|
&& (type2 == VAR_NUMBER || type2 == VAR_FLOAT
|
||||||
|| type2 == VAR_ANY)))
|
|| type2 == VAR_ANY || type2 == VAR_UNKNOWN)))
|
||||||
{
|
{
|
||||||
if (*op == '+')
|
if (*op == '+')
|
||||||
emsg(_(e_wrong_argument_type_for_plus));
|
emsg(_(e_wrong_argument_type_for_plus));
|
||||||
@@ -204,7 +205,9 @@ generate_add_instr(
|
|||||||
|
|
||||||
if (vartype != VAR_LIST && vartype != VAR_BLOB
|
if (vartype != VAR_LIST && vartype != VAR_BLOB
|
||||||
&& type1->tt_type != VAR_ANY
|
&& type1->tt_type != VAR_ANY
|
||||||
|
&& type1->tt_type != VAR_UNKNOWN
|
||||||
&& type2->tt_type != VAR_ANY
|
&& type2->tt_type != VAR_ANY
|
||||||
|
&& type2->tt_type != VAR_UNKNOWN
|
||||||
&& check_number_or_float(
|
&& check_number_or_float(
|
||||||
type1->tt_type, type2->tt_type, (char_u *)"+") == FAIL)
|
type1->tt_type, type2->tt_type, (char_u *)"+") == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -293,8 +296,10 @@ generate_two_op(cctx_T *cctx, char_u *op)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '%': if ((type1->tt_type != VAR_ANY
|
case '%': if ((type1->tt_type != VAR_ANY
|
||||||
|
&& type1->tt_type != VAR_UNKNOWN
|
||||||
&& type1->tt_type != VAR_NUMBER)
|
&& type1->tt_type != VAR_NUMBER)
|
||||||
|| (type2->tt_type != VAR_ANY
|
|| (type2->tt_type != VAR_ANY
|
||||||
|
&& type2->tt_type != VAR_UNKNOWN
|
||||||
&& type2->tt_type != VAR_NUMBER))
|
&& type2->tt_type != VAR_NUMBER))
|
||||||
{
|
{
|
||||||
emsg(_(e_percent_requires_number_arguments));
|
emsg(_(e_percent_requires_number_arguments));
|
||||||
@@ -1528,7 +1533,7 @@ generate_PCALL(
|
|||||||
|
|
||||||
RETURN_OK_IF_SKIP(cctx);
|
RETURN_OK_IF_SKIP(cctx);
|
||||||
|
|
||||||
if (type->tt_type == VAR_ANY)
|
if (type->tt_type == VAR_ANY || type->tt_type == VAR_UNKNOWN)
|
||||||
ret_type = &t_any;
|
ret_type = &t_any;
|
||||||
else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
|
else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
|
||||||
{
|
{
|
||||||
@@ -1620,7 +1625,7 @@ generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len)
|
|||||||
|
|
||||||
// check for dict type
|
// check for dict type
|
||||||
type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
if (type->tt_type != VAR_DICT && type != &t_any)
|
if (type->tt_type != VAR_DICT && type != &t_any && type != &t_unknown)
|
||||||
{
|
{
|
||||||
char *tofree;
|
char *tofree;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user