patch 8.2.0755: Vim9: No error when variable initializer is not a constant
Problem: Vim9: No error when variable initializer is not a constant.
Solution: Return FAIL when trying to get a variable value. Do not execute a
script when an error is deteted in the first or second phase.
diff --git a/src/eval.c b/src/eval.c
index b3fe650..77359dc 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2695,6 +2695,8 @@
{
if (**arg == '(') // recursive!
ret = eval_func(arg, s, len, rettv, flags, NULL);
+ else if (flags & EVAL_CONSTANT)
+ ret = FAIL;
else if (evaluate)
ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE);
else
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 6b6228e..fd1dbc8 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -494,8 +494,8 @@
def Concat(arg: string): string
return name .. arg
enddef
- let g:result: string = Concat('bie')
- let g:localname = name
+ g:result = Concat('bie')
+ g:localname = name
export const CONST = 1234
export let exported = 9876
@@ -1747,10 +1747,34 @@
endfunc
let val = GetValue()
END
- writefile(lines, 'Xfinished')
- assert_fails('source Xfinished', 'E1091:')
+ CheckScriptFailure(lines, 'E1091:')
- delete('Xfinished')
+ lines =<< trim END
+ vim9script
+ let var = g:unkown
+ END
+ CheckScriptFailure(lines, 'E1091:')
+
+ " TODO: eventually this would work
+ lines =<< trim END
+ vim9script
+ let var = has('eval')
+ END
+ CheckScriptFailure(lines, 'E1091:')
+
+ " TODO: eventually this would work
+ lines =<< trim END
+ vim9script
+ let var = len('string')
+ END
+ CheckScriptFailure(lines, 'E1091:')
+
+ lines =<< trim END
+ vim9script
+ let nr: number = 123
+ let var = nr
+ END
+ CheckScriptFailure(lines, 'E1091:')
enddef
def Test_forward_declaration()
diff --git a/src/version.c b/src/version.c
index 8ff5161..1f77ddc 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 755,
+/**/
754,
/**/
753,
diff --git a/src/vim9script.c b/src/vim9script.c
index 4d7e8ee..e213d61 100644
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -37,6 +37,7 @@
garray_T func_ga;
int idx;
ufunc_T *ufunc;
+ int start_called_emsg = called_emsg;
if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
@@ -66,7 +67,7 @@
// The types are recognized, so that they can be used when compiling a
// function.
gap = source_get_line_ga(eap->cookie);
- for (;;)
+ while (called_emsg == start_called_emsg)
{
char_u *line;
char_u *p;
@@ -132,22 +133,29 @@
}
else if (checkforcmd(&p, "finish", 4))
{
- // TODO: this should not happen below "if false".
- // Use "if cond | finish | endif as a workaround.
break;
}
}
// Compile the :def functions.
- for (idx = 0; idx < func_ga.ga_len; ++idx)
+ for (idx = 0; idx < func_ga.ga_len && called_emsg == start_called_emsg; ++idx)
{
ufunc = ((ufunc_T **)(func_ga.ga_data))[idx];
compile_def_function(ufunc, FALSE, NULL);
}
ga_clear(&func_ga);
- // Return to process the commands at the script level.
- source_use_line_ga(eap->cookie);
+ if (called_emsg == start_called_emsg)
+ {
+ // Return to process the commands at the script level.
+ source_use_line_ga(eap->cookie);
+ }
+ else
+ {
+ // If there was an error in the first or second phase then don't
+ // execute the script lines.
+ do_finish(eap, FALSE);
+ }
}
/*