patch 9.1.1788: Vim9: can declare a void variable
Problem: Vim9: can declare a void variable (Ernie Rael) Solution: Disallow such variable declaration (Yegappan Lakshmanan) fixes: #13773 closes: #18382 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
a7680a1a69
commit
7376fa3fd8
@ -3415,8 +3415,8 @@ EXTERN char e_constructor_default_value_must_be_vnone_str[]
|
||||
INIT(= N_("E1328: Constructor default value must be v:none: %s"));
|
||||
EXTERN char e_invalid_class_variable_declaration_str[]
|
||||
INIT(= N_("E1329: Invalid class variable declaration: %s"));
|
||||
EXTERN char e_invalid_type_for_object_variable_str[]
|
||||
INIT(= N_("E1330: Invalid type for object variable: %s"));
|
||||
EXTERN char e_invalid_type_in_variable_declaration_str[]
|
||||
INIT(= N_("E1330: Invalid type used in variable declaration: %s"));
|
||||
EXTERN char e_public_must_be_followed_by_var_static_final_or_const[]
|
||||
INIT(= N_("E1331: public must be followed by \"var\" or \"static\" or \"final\" or \"const\""));
|
||||
EXTERN char e_public_variable_name_cannot_start_with_underscore_str[]
|
||||
|
||||
@ -2223,7 +2223,8 @@ get_lval(
|
||||
lp->ll_type = parse_type(&tp,
|
||||
&SCRIPT_ITEM(current_sctx.sc_sid)->sn_type_list,
|
||||
NULL, NULL, !quiet);
|
||||
if (lp->ll_type == NULL && !quiet)
|
||||
if (!quiet && (lp->ll_type == NULL
|
||||
|| !valid_declaration_type(lp->ll_type)))
|
||||
return NULL;
|
||||
lp->ll_name_end = tp;
|
||||
}
|
||||
|
||||
4
src/po/vim.pot
generated
4
src/po/vim.pot
generated
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Vim\n"
|
||||
"Report-Msgid-Bugs-To: vim-dev@vim.org\n"
|
||||
"POT-Creation-Date: 2025-09-22 19:04+0000\n"
|
||||
"POT-Creation-Date: 2025-09-24 17:48+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -8228,7 +8228,7 @@ msgid "E1329: Invalid class variable declaration: %s"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "E1330: Invalid type for object variable: %s"
|
||||
msgid "E1330: Invalid type used in variable declaration: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
|
||||
@ -2339,6 +2339,97 @@ def Test_var_declaration_fails()
|
||||
endfor
|
||||
enddef
|
||||
|
||||
" Test for using "void" as the type in a variable declaration
|
||||
def Test_var_declaration_void_type()
|
||||
# Using void as the type of a local variable
|
||||
var lines =<< trim END
|
||||
var x: void
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the type of a function argument
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
def Foo(x: void)
|
||||
enddef
|
||||
defcompile
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1330: Invalid type used in variable declaration: void', 2)
|
||||
|
||||
# Using void as the type of a variable with a initializer
|
||||
lines =<< trim END
|
||||
var a: void = 10
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the list item type
|
||||
lines =<< trim END
|
||||
var l: list<void> = []
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the tuple item type
|
||||
lines =<< trim END
|
||||
var t: tuple<void> = ()
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the dict item type
|
||||
lines =<< trim END
|
||||
var l: dict<void> = {}
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the argument type in a lambda
|
||||
lines =<< trim END
|
||||
var Fn = (x: void) => x
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the type of an object member variable
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
class A
|
||||
var x: void = 1
|
||||
endclass
|
||||
var a = A.new()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the type of a loop index
|
||||
lines =<< trim END
|
||||
for [i: number, j: void] in ((1, 2), (3, 4))
|
||||
endfor
|
||||
END
|
||||
v9.CheckDefFailure(lines, 'E1330: Invalid type used in variable declaration: void')
|
||||
|
||||
# Using void as the type of a generic parameter
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
def Fn<T, U>()
|
||||
enddef
|
||||
Fn<void, void>()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1330: Invalid type used in variable declaration: void', 4)
|
||||
|
||||
# Using void as the type of a parameter in a function type
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
def Foo()
|
||||
enddef
|
||||
var Fn: func(void): void = Foo
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1330: Invalid type used in variable declaration: void', 4)
|
||||
|
||||
# Using void in a type alias
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type MyType = void
|
||||
var x: MyType
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1330: Invalid type used in variable declaration: void', 3)
|
||||
enddef
|
||||
|
||||
def Test_var_declaration_inferred()
|
||||
# check that type is set on the list so that extend() fails
|
||||
var lines =<< trim END
|
||||
|
||||
@ -1258,7 +1258,7 @@ def Test_class_object_member_inits()
|
||||
var value: void
|
||||
endclass
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
|
||||
v9.CheckSourceFailure(lines, 'E1330: Invalid type used in variable declaration: void', 3)
|
||||
enddef
|
||||
|
||||
" Test for instance variable access
|
||||
|
||||
@ -573,7 +573,7 @@ parse_argument_types(
|
||||
else
|
||||
type = parse_type(&p, &fp->uf_type_list, fp, cctx, TRUE);
|
||||
}
|
||||
if (type == NULL)
|
||||
if (type == NULL || !valid_declaration_type(type))
|
||||
return FAIL;
|
||||
fp->uf_arg_types[i] = type;
|
||||
if (i < fp->uf_args.ga_len
|
||||
|
||||
@ -729,6 +729,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1788,
|
||||
/**/
|
||||
1787,
|
||||
/**/
|
||||
|
||||
@ -102,7 +102,7 @@ parse_member(
|
||||
}
|
||||
type_arg = skipwhite(colon + 1);
|
||||
type = parse_type(&type_arg, type_list, NULL, NULL, TRUE);
|
||||
if (type == NULL)
|
||||
if (type == NULL || !valid_declaration_type(type))
|
||||
return FAIL;
|
||||
*has_type = TRUE;
|
||||
}
|
||||
|
||||
@ -1132,7 +1132,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
||||
p = skipwhite(p + 1);
|
||||
lhs_type = parse_type(&p, cctx->ctx_type_list, cctx->ctx_ufunc,
|
||||
cctx, TRUE);
|
||||
if (lhs_type == NULL)
|
||||
if (lhs_type == NULL || !valid_declaration_type(lhs_type))
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
@ -2121,7 +2121,8 @@ compile_lhs_set_type(cctx_T *cctx, lhs_T *lhs, char_u *var_end, int is_decl)
|
||||
|
||||
p = skipwhite(var_end + 1);
|
||||
lhs->lhs_type = parse_type(&p, cctx->ctx_type_list, cctx->ctx_ufunc, cctx, TRUE);
|
||||
if (lhs->lhs_type == NULL)
|
||||
if (lhs->lhs_type == NULL
|
||||
|| !valid_declaration_type(lhs->lhs_type))
|
||||
return FAIL;
|
||||
|
||||
lhs->lhs_has_type = TRUE;
|
||||
|
||||
@ -306,7 +306,7 @@ parse_generic_func_type_args(
|
||||
|
||||
// parse the type
|
||||
type_arg = parse_type(&p, &gfatab->gfat_arg_types, NULL, cctx, TRUE);
|
||||
if (type_arg == NULL)
|
||||
if (type_arg == NULL || !valid_declaration_type(type_arg))
|
||||
return NULL;
|
||||
|
||||
char *ret_free = NULL;
|
||||
|
||||
@ -841,7 +841,9 @@ vim9_declare_scriptvar(exarg_T *eap, char_u *arg)
|
||||
// parse type, check for reserved name
|
||||
p = skipwhite(p + 1);
|
||||
type = parse_type(&p, &si->sn_type_list, NULL, NULL, TRUE);
|
||||
if (type == NULL || check_reserved_name(name, FALSE) == FAIL)
|
||||
if (type == NULL
|
||||
|| check_reserved_name(name, FALSE) == FAIL
|
||||
|| !valid_declaration_type(type))
|
||||
{
|
||||
vim_free(name);
|
||||
return p;
|
||||
|
||||
@ -997,7 +997,7 @@ valid_declaration_type(type_T *type)
|
||||
{
|
||||
char *tofree = NULL;
|
||||
char *name = type_name(type, &tofree);
|
||||
semsg(_(e_invalid_type_for_object_variable_str), name);
|
||||
semsg(_(e_invalid_type_in_variable_declaration_str), name);
|
||||
vim_free(tofree);
|
||||
return FALSE;
|
||||
}
|
||||
@ -1629,7 +1629,7 @@ parse_type_member(
|
||||
*arg = skipwhite(*arg + 1);
|
||||
|
||||
member_type = parse_type(arg, type_gap, ufunc, cctx, give_error);
|
||||
if (member_type == NULL)
|
||||
if (member_type == NULL || !valid_declaration_type(member_type))
|
||||
return NULL;
|
||||
|
||||
*arg = skipwhite(*arg);
|
||||
@ -1699,7 +1699,7 @@ parse_type_func(
|
||||
}
|
||||
|
||||
type = parse_type(&p, type_gap, ufunc, cctx, give_error);
|
||||
if (type == NULL)
|
||||
if (type == NULL || !valid_declaration_type(type))
|
||||
return NULL;
|
||||
if ((flags & TTFLAG_VARARGS) != 0 && type->tt_type != VAR_LIST)
|
||||
{
|
||||
@ -1831,7 +1831,7 @@ parse_type_tuple(
|
||||
}
|
||||
|
||||
type = parse_type(&p, type_gap, ufunc, cctx, give_error);
|
||||
if (type == NULL)
|
||||
if (type == NULL || !valid_declaration_type(type))
|
||||
goto on_err;
|
||||
|
||||
if ((flags & TTFLAG_VARARGS) != 0 && type->tt_type != VAR_LIST)
|
||||
|
||||
Reference in New Issue
Block a user