mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.0820: Vim9: function type isn't set until compiled
Problem: Vim9: function type isn't set until compiled. Solution: Set function type early.
This commit is contained in:
@@ -10,6 +10,7 @@ char_u *to_name_const_end(char_u *arg);
|
||||
int assignment_len(char_u *p, int *heredoc);
|
||||
int check_vim9_unlet(char_u *name);
|
||||
int compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx);
|
||||
void set_function_type(ufunc_T *ufunc);
|
||||
void delete_instr(isn_T *isn);
|
||||
void delete_def_function(ufunc_T *ufunc);
|
||||
void free_def_functions(void);
|
||||
|
@@ -560,8 +560,7 @@ def Test_func_type_part()
|
||||
RefVoid = FuncNoArgNoRet
|
||||
RefVoid = FuncOneArgNoRet
|
||||
CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
|
||||
" TODO: these should fail
|
||||
" CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string')
|
||||
CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string')
|
||||
|
||||
let RefAny: func(): any
|
||||
RefAny = FuncNoArgRetNumber
|
||||
@@ -573,8 +572,7 @@ def Test_func_type_part()
|
||||
RefNr = FuncNoArgRetNumber
|
||||
RefNr = FuncOneArgRetNumber
|
||||
CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()')
|
||||
" TODO: should fail
|
||||
" CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string')
|
||||
CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string')
|
||||
|
||||
let RefStr: func: string
|
||||
RefStr = FuncNoArgRetString
|
||||
@@ -589,10 +587,9 @@ def Test_func_type_fails()
|
||||
CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
|
||||
CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)')
|
||||
CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number')
|
||||
" TODO: these don't fail
|
||||
" CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)')
|
||||
" CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)')
|
||||
" CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)')
|
||||
CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)')
|
||||
CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)')
|
||||
CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)')
|
||||
|
||||
call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:')
|
||||
call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:')
|
||||
|
@@ -3284,6 +3284,9 @@ def_function(exarg_T *eap, char_u *name_arg)
|
||||
is_export = FALSE;
|
||||
}
|
||||
|
||||
if (eap->cmdidx == CMD_def)
|
||||
set_function_type(fp);
|
||||
|
||||
goto ret_free;
|
||||
|
||||
erret:
|
||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
820,
|
||||
/**/
|
||||
819,
|
||||
/**/
|
||||
|
@@ -6763,54 +6763,6 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
ufunc->uf_flags |= FC_CLOSURE;
|
||||
}
|
||||
|
||||
{
|
||||
int varargs = ufunc->uf_va_name != NULL;
|
||||
int argcount = ufunc->uf_args.ga_len;
|
||||
|
||||
// Create a type for the function, with the return type and any
|
||||
// argument types.
|
||||
// A vararg is included in uf_args.ga_len but not in uf_arg_types.
|
||||
// The type is included in "tt_args".
|
||||
if (argcount > 0 || varargs)
|
||||
{
|
||||
ufunc->uf_func_type = alloc_func_type(ufunc->uf_ret_type,
|
||||
argcount, &ufunc->uf_type_list);
|
||||
// Add argument types to the function type.
|
||||
if (func_type_add_arg_types(ufunc->uf_func_type,
|
||||
argcount + varargs,
|
||||
&ufunc->uf_type_list) == FAIL)
|
||||
{
|
||||
ret = FAIL;
|
||||
goto erret;
|
||||
}
|
||||
ufunc->uf_func_type->tt_argcount = argcount + varargs;
|
||||
ufunc->uf_func_type->tt_min_argcount =
|
||||
argcount - ufunc->uf_def_args.ga_len;
|
||||
if (ufunc->uf_arg_types == NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
// lambda does not have argument types.
|
||||
for (i = 0; i < argcount; ++i)
|
||||
ufunc->uf_func_type->tt_args[i] = &t_any;
|
||||
}
|
||||
else
|
||||
mch_memmove(ufunc->uf_func_type->tt_args,
|
||||
ufunc->uf_arg_types, sizeof(type_T *) * argcount);
|
||||
if (varargs)
|
||||
{
|
||||
ufunc->uf_func_type->tt_args[argcount] =
|
||||
ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
|
||||
ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS;
|
||||
}
|
||||
}
|
||||
else
|
||||
// No arguments, can use a predefined type.
|
||||
ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type,
|
||||
argcount, &ufunc->uf_type_list);
|
||||
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
|
||||
erret:
|
||||
@@ -6847,6 +6799,53 @@ erret:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
set_function_type(ufunc_T *ufunc)
|
||||
{
|
||||
int varargs = ufunc->uf_va_name != NULL;
|
||||
int argcount = ufunc->uf_args.ga_len;
|
||||
|
||||
// Create a type for the function, with the return type and any
|
||||
// argument types.
|
||||
// A vararg is included in uf_args.ga_len but not in uf_arg_types.
|
||||
// The type is included in "tt_args".
|
||||
if (argcount > 0 || varargs)
|
||||
{
|
||||
ufunc->uf_func_type = alloc_func_type(ufunc->uf_ret_type,
|
||||
argcount, &ufunc->uf_type_list);
|
||||
// Add argument types to the function type.
|
||||
if (func_type_add_arg_types(ufunc->uf_func_type,
|
||||
argcount + varargs,
|
||||
&ufunc->uf_type_list) == FAIL)
|
||||
return;
|
||||
ufunc->uf_func_type->tt_argcount = argcount + varargs;
|
||||
ufunc->uf_func_type->tt_min_argcount =
|
||||
argcount - ufunc->uf_def_args.ga_len;
|
||||
if (ufunc->uf_arg_types == NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
// lambda does not have argument types.
|
||||
for (i = 0; i < argcount; ++i)
|
||||
ufunc->uf_func_type->tt_args[i] = &t_any;
|
||||
}
|
||||
else
|
||||
mch_memmove(ufunc->uf_func_type->tt_args,
|
||||
ufunc->uf_arg_types, sizeof(type_T *) * argcount);
|
||||
if (varargs)
|
||||
{
|
||||
ufunc->uf_func_type->tt_args[argcount] =
|
||||
ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
|
||||
ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS;
|
||||
}
|
||||
}
|
||||
else
|
||||
// No arguments, can use a predefined type.
|
||||
ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type,
|
||||
argcount, &ufunc->uf_type_list);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Delete an instruction, free what it contains.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user