0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 9.0.1558: wrong error for unreachable code after :throw

Problem:    Wrong error for unreachable code after :throw.
Solution:   Adjust the error message.
This commit is contained in:
Bram Moolenaar
2023-05-14 22:05:15 +01:00
parent 9d383f30bb
commit a2c0028fdf
5 changed files with 39 additions and 6 deletions

View File

@@ -2809,8 +2809,8 @@ EXTERN char e_expected_nr_items_but_got_nr[]
INIT(= N_("E1093: Expected %d items but got %d")); INIT(= N_("E1093: Expected %d items but got %d"));
EXTERN char e_import_can_only_be_used_in_script[] EXTERN char e_import_can_only_be_used_in_script[]
INIT(= N_("E1094: Import can only be used in a script")); INIT(= N_("E1094: Import can only be used in a script"));
EXTERN char e_unreachable_code_after_return[] EXTERN char e_unreachable_code_after_str[]
INIT(= N_("E1095: Unreachable code after :return")); INIT(= N_("E1095: Unreachable code after :%s"));
EXTERN char e_returning_value_in_function_without_return_type[] EXTERN char e_returning_value_in_function_without_return_type[]
INIT(= N_("E1096: Returning a value in a function without a return type")); INIT(= N_("E1096: Returning a value in a function without a return type"));
EXTERN char e_line_incomplete[] EXTERN char e_line_incomplete[]

View File

@@ -812,6 +812,30 @@ def Test_try_catch_throw()
v9.CheckDefAndScriptSuccess(lines) v9.CheckDefAndScriptSuccess(lines)
enddef enddef
def Test_unreachable_after()
var lines =<< trim END
try
throw 'Error'
echo 'not reached'
catch /Error/
endtry
END
v9.CheckDefFailure(lines, 'E1095: Unreachable code after :throw')
lines =<< trim END
def SomeFunc(): number
try
return 3
echo 'not reached'
catch /Error/
endtry
return 4
enddef
defcompile
END
v9.CheckScriptFailure(lines, 'E1095: Unreachable code after :return')
enddef
def Test_throw_in_nested_try() def Test_throw_in_nested_try()
var lines =<< trim END var lines =<< trim END
vim9script vim9script
@@ -1079,6 +1103,8 @@ def Test_nocatch_throw_silenced()
source XthrowSilenced source XthrowSilenced
enddef enddef
" g:DeletedFunc() is found when compiling Test_try_catch_throw() and then
" deleted, this should give a runtime error.
def DeletedFunc(): list<any> def DeletedFunc(): list<any>
return ['delete me'] return ['delete me']
enddef enddef

View File

@@ -695,6 +695,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 */
/**/
1558,
/**/ /**/
1557, 1557,
/**/ /**/

View File

@@ -842,6 +842,7 @@ struct cctx_S {
skip_T ctx_skip; skip_T ctx_skip;
scope_T *ctx_scope; // current scope, NULL at toplevel scope_T *ctx_scope; // current scope, NULL at toplevel
int ctx_had_return; // last seen statement was "return" int ctx_had_return; // last seen statement was "return"
int ctx_had_throw; // last seen statement was "throw"
cctx_T *ctx_outer; // outer scope for lambda or nested cctx_T *ctx_outer; // outer scope for lambda or nested
// function // function

View File

@@ -3485,7 +3485,7 @@ compile_def_function(
} }
} }
if (cctx.ctx_had_return if ((cctx.ctx_had_return || cctx.ctx_had_throw)
&& ea.cmdidx != CMD_elseif && ea.cmdidx != CMD_elseif
&& ea.cmdidx != CMD_else && ea.cmdidx != CMD_else
&& ea.cmdidx != CMD_endif && ea.cmdidx != CMD_endif
@@ -3496,9 +3496,11 @@ compile_def_function(
&& ea.cmdidx != CMD_endtry && ea.cmdidx != CMD_endtry
&& !ignore_unreachable_code_for_testing) && !ignore_unreachable_code_for_testing)
{ {
emsg(_(e_unreachable_code_after_return)); semsg(_(e_unreachable_code_after_str),
cctx.ctx_had_return ? "return" : "throw");
goto erret; goto erret;
} }
cctx.ctx_had_throw = FALSE;
p = skipwhite(p); p = skipwhite(p);
if (ea.cmdidx != CMD_SIZE if (ea.cmdidx != CMD_SIZE
@@ -3612,7 +3614,7 @@ compile_def_function(
break; break;
case CMD_throw: case CMD_throw:
line = compile_throw(p, &cctx); line = compile_throw(p, &cctx);
cctx.ctx_had_return = TRUE; cctx.ctx_had_throw = TRUE;
break; break;
case CMD_eval: case CMD_eval:
@@ -3765,7 +3767,9 @@ nextline:
goto erret; goto erret;
} }
if (!cctx.ctx_had_return) // TODO: if a function ends in "throw" but there was a return elsewhere we
// should not assume the return type is "void".
if (!cctx.ctx_had_return && !cctx.ctx_had_throw)
{ {
if (ufunc->uf_ret_type->tt_type == VAR_UNKNOWN) if (ufunc->uf_ret_type->tt_type == VAR_UNKNOWN)
ufunc->uf_ret_type = &t_void; ufunc->uf_ret_type = &t_void;