summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-05-09 23:19:22 +0200
committerBram Moolenaar <Bram@vim.org>2021-05-09 23:19:22 +0200
commit68db996b621b98066fb7ab7028ed5c6aaa3954a8 (patch)
tree1f2bdef2e7049b051dcbe12c5effde327322b3eb
parent918b08957c51ae079f8f456198f8a1869a3d2a4c (diff)
patch 8.2.2846: Vim9: "echo Func()" does not give an error for using voidv8.2.2846
Problem: Vim9: "echo Func()" does not give an error for a function without a return value. Solution: Give an error. Be more specific about why a value is invalid.
-rw-r--r--src/errors.h4
-rw-r--r--src/eval.c19
-rw-r--r--src/evalfunc.c3
-rw-r--r--src/globals.h1
-rw-r--r--src/testdir/test_vim9_cmd.vim23
-rw-r--r--src/typval.c3
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c16
-rw-r--r--src/vim9execute.c3
9 files changed, 65 insertions, 9 deletions
diff --git a/src/errors.h b/src/errors.h
index 3d12c1d633..2a0a536c84 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -31,6 +31,8 @@ EXTERN char e_cannot_slice_dictionary[]
INIT(= N_("E719: Cannot slice a Dictionary"));
EXTERN char e_assert_fails_second_arg[]
INIT(= N_("E856: \"assert_fails()\" second argument must be a string or a list with one or two strings"));
+EXTERN char e_using_invalid_value_as_string_str[]
+ INIT(= N_("E908: using an invalid value as a String: %s"));
EXTERN char e_cannot_index_special_variable[]
INIT(= N_("E909: Cannot index a special variable"));
#endif
@@ -409,3 +411,5 @@ EXTERN char e_cannot_nest_redir[]
INIT(= N_("E1185: Cannot nest :redir"));
EXTERN char e_missing_redir_end[]
INIT(= N_("E1185: Missing :redir END"));
+EXTERN char e_expression_does_not_result_in_value_str[]
+ INIT(= N_("E1186: Expression does not result in a value: %s"));
diff --git a/src/eval.c b/src/eval.c
index bf9e8ee721..aa3d0a1ec8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2951,7 +2951,8 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
if (vim9script && (var2.v_type == VAR_VOID
|| var2.v_type == VAR_CHANNEL
|| var2.v_type == VAR_JOB))
- emsg(_(e_inval_string));
+ semsg(_(e_using_invalid_value_as_string_str),
+ vartype_name(var2.v_type));
#ifdef FEAT_FLOAT
else if (vim9script && var2.v_type == VAR_FLOAT)
{
@@ -6110,7 +6111,7 @@ ex_echo(exarg_T *eap)
{
char_u *arg = eap->arg;
typval_T rettv;
- char_u *p;
+ char_u *arg_start;
int needclr = TRUE;
int atstart = TRUE;
int did_emsg_before = did_emsg;
@@ -6127,7 +6128,7 @@ ex_echo(exarg_T *eap)
// still need to be cleared. E.g., "echo 22,44".
need_clr_eos = needclr;
- p = arg;
+ arg_start = arg;
if (eval1(&arg, &rettv, &evalarg) == FAIL)
{
/*
@@ -6137,14 +6138,21 @@ ex_echo(exarg_T *eap)
*/
if (!aborting() && did_emsg == did_emsg_before
&& called_emsg == called_emsg_before)
- semsg(_(e_invexpr2), p);
+ semsg(_(e_invexpr2), arg_start);
need_clr_eos = FALSE;
break;
}
need_clr_eos = FALSE;
if (!eap->skip)
+ {
+ if (rettv.v_type == VAR_VOID)
+ {
+ semsg(_(e_expression_does_not_result_in_value_str), arg_start);
+ break;
+ }
echo_one(&rettv, eap->cmdidx == CMD_echo, &atstart, &needclr);
+ }
clear_tv(&rettv);
arg = skipwhite(arg);
@@ -6218,7 +6226,8 @@ ex_execute(exarg_T *eap)
{
if (rettv.v_type == VAR_CHANNEL || rettv.v_type == VAR_JOB)
{
- emsg(_(e_inval_string));
+ semsg(_(e_using_invalid_value_as_string_str),
+ vartype_name(rettv.v_type));
p = NULL;
}
else
diff --git a/src/evalfunc.c b/src/evalfunc.c
index a0caf3dce8..6a2244961e 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3175,7 +3175,8 @@ execute_common(typval_T *argvars, typval_T *rettv, int arg_off)
else if (argvars[arg_off].v_type == VAR_JOB
|| argvars[arg_off].v_type == VAR_CHANNEL)
{
- emsg(_(e_inval_string));
+ semsg(_(e_using_invalid_value_as_string_str),
+ vartype_name(argvars[arg_off].v_type));
return;
}
else
diff --git a/src/globals.h b/src/globals.h
index b6541a4f4f..0a6b87a780 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1728,7 +1728,6 @@ EXTERN char e_list_end[] INIT(= N_("E697: Missing end of List ']': %s"));
EXTERN char e_listdictarg[] INIT(= N_("E712: Argument of %s must be a List or Dictionary"));
EXTERN char e_listdictblobarg[] INIT(= N_("E896: Argument of %s must be a List, Dictionary or Blob"));
EXTERN char e_modulus[] INIT(= N_("E804: Cannot use '%' with Float"));
-EXTERN char e_inval_string[] INIT(= N_("E908: using an invalid value as a String"));
EXTERN char e_const_option[] INIT(= N_("E996: Cannot lock an option"));
EXTERN char e_unknown_option[] INIT(= N_("E113: Unknown option: %s"));
EXTERN char e_letunexp[] INIT(= N_("E18: Unexpected characters in :let"));
diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index 080fe20cc1..87832ce2eb 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -1282,5 +1282,28 @@ def Test_redir_to_var()
CheckDefFailure(lines, 'E1141:')
enddef
+def Test_echo_void()
+ var lines =<< trim END
+ vim9script
+ def NoReturn()
+ echo 'nothing'
+ enddef
+ echo NoReturn()
+ END
+ CheckScriptFailure(lines, 'E1186:', 5)
+
+ lines =<< trim END
+ vim9script
+ def NoReturn()
+ echo 'nothing'
+ enddef
+ def Try()
+ echo NoReturn()
+ enddef
+ defcompile
+ END
+ CheckScriptFailure(lines, 'E1186:', 1)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/typval.c b/src/typval.c
index 9ca35699d5..3d1bd7f53f 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -522,7 +522,8 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
case VAR_ANY:
case VAR_VOID:
case VAR_INSTR:
- emsg(_(e_inval_string));
+ semsg(_(e_using_invalid_value_as_string_str),
+ vartype_name(varp->v_type));
break;
}
return NULL;
diff --git a/src/version.c b/src/version.c
index e8827c4602..4843be1318 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2846,
+/**/
2845,
/**/
2844,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index fd32660e07..39c36dfb24 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -8375,15 +8375,31 @@ compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
{
char_u *p = arg;
char_u *prev = arg;
+ char_u *expr_start;
int count = 0;
int start_ctx_lnum = cctx->ctx_lnum;
+ garray_T *stack = &cctx->ctx_type_stack;
+ type_T *type;
for (;;)
{
if (ends_excmd2(prev, p))
break;
+ expr_start = p;
if (compile_expr0(&p, cctx) == FAIL)
return NULL;
+
+ if (cctx->ctx_skip != SKIP_YES)
+ {
+ // check for non-void type
+ type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
+ if (type->tt_type == VAR_VOID)
+ {
+ semsg(_(e_expression_does_not_result_in_value_str), expr_start);
+ return NULL;
+ }
+ }
+
++count;
prev = p;
p = skipwhite(p);
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 29cd5fc67a..ae4142b0ce 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1578,7 +1578,8 @@ exec_instructions(ectx_T *ectx)
|| tv->v_type == VAR_JOB)
{
SOURCING_LNUM = iptr->isn_lnum;
- emsg(_(e_inval_string));
+ semsg(_(e_using_invalid_value_as_string_str),
+ vartype_name(tv->v_type));
break;
}
else