diff --git a/src/errors.h b/src/errors.h index 91b1c944f3..771f4976d4 100644 --- a/src/errors.h +++ b/src/errors.h @@ -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[] diff --git a/src/eval.c b/src/eval.c index 503623491c..4a55adac72 100644 --- a/src/eval.c +++ b/src/eval.c @@ -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; } diff --git a/src/po/vim.pot b/src/po/vim.pot index 20571200d1..fb369d7d19 100644 --- a/src/po/vim.pot +++ b/src/po/vim.pot @@ -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 \n" "Language-Team: LANGUAGE \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 "" diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 0872081902..6021148597 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -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 = [] + 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 = () + 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 = {} + 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() + enddef + Fn() + 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 diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index fc38898317..467d0d1fcf 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -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 diff --git a/src/userfunc.c b/src/userfunc.c index a4d01524ab..1dead04302 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -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 diff --git a/src/version.c b/src/version.c index b43aa13283..bad197898e 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1788, /**/ 1787, /**/ diff --git a/src/vim9class.c b/src/vim9class.c index 40b594af79..f6566e2ef1 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -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; } diff --git a/src/vim9cmds.c b/src/vim9cmds.c index da57912ad7..668c9a1552 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -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; } diff --git a/src/vim9compile.c b/src/vim9compile.c index 65e0ff1943..91c1c0c9ed 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -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; diff --git a/src/vim9generics.c b/src/vim9generics.c index 54400903e4..7afedad391 100644 --- a/src/vim9generics.c +++ b/src/vim9generics.c @@ -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; diff --git a/src/vim9script.c b/src/vim9script.c index e526637e27..435ca2de86 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -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; diff --git a/src/vim9type.c b/src/vim9type.c index 28997ab37b..e36f956690 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -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)