Skip to content

Commit f9b2b49

Browse files
committed
patch 8.2.1373: Vim9: no error for assigning to non-existing script var
Problem: Vim9: no error for assigning to non-existing script var. Solution: Check that in Vim9 script the variable was defined. (closes #6630)
1 parent fdac71c commit f9b2b49

5 files changed

Lines changed: 68 additions & 36 deletions

File tree

src/structs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,9 @@ typedef struct
15941594
int uf_tml_execed; // line being timed was executed
15951595
# endif
15961596
sctx_T uf_script_ctx; // SCTX where function was defined,
1597-
// used for s: variables
1597+
// used for s: variables; sc_version changed
1598+
// for :function
1599+
int uf_script_ctx_version; // original sc_version of SCTX
15981600
int uf_refcount; // reference count, see func_name_refcount()
15991601

16001602
funccall_T *uf_scoped; // l: local variables for closure

src/testdir/test_vim9_script.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ def Test_assignment()
112112
call CheckDefFailure(['let s:var = 123'], 'E1101:')
113113
call CheckDefFailure(['let s:var: number'], 'E1101:')
114114

115+
lines =<< trim END
116+
vim9script
117+
def SomeFunc()
118+
s:var = 123
119+
enddef
120+
defcompile
121+
END
122+
call CheckScriptFailure(lines, 'E1089:')
123+
115124
g:inc_counter += 1
116125
assert_equal(2, g:inc_counter)
117126

src/userfunc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,6 +3508,7 @@ def_function(exarg_T *eap, char_u *name_arg)
35083508
fp->uf_calls = 0;
35093509
fp->uf_cleared = FALSE;
35103510
fp->uf_script_ctx = current_sctx;
3511+
fp->uf_script_ctx_version = current_sctx.sc_version;
35113512
fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
35123513
if (is_export)
35133514
{

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ static char *(features[]) =
754754

755755
static int included_patches[] =
756756
{ /* Add new patch number below this line */
757+
/**/
758+
1373,
757759
/**/
758760
1372,
759761
/**/

src/vim9compile.c

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ static char e_syntax_at[] = N_("E1002: Syntax error at %s");
148148
static char e_used_as_arg[] = N_("E1006: %s is used as an argument");
149149
static char e_cannot_use_void[] = N_("E1031: Cannot use void value");
150150
static char e_namespace[] = N_("E1075: Namespace not supported: %s");
151+
static char e_unknown_var[] = N_("E1089: unknown variable: %s");
151152

152153
static void delete_def_function_contents(dfunc_T *dfunc);
153154
static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx);
@@ -5335,7 +5336,6 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
53355336
else
53365337
{
53375338
int idx;
5338-
imported_T *import = NULL;
53395339

53405340
for (idx = 0; reserved[idx] != NULL; ++idx)
53415341
if (STRCMP(reserved[idx], name) == 0)
@@ -5374,49 +5374,67 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
53745374
goto theend;
53755375
}
53765376
}
5377-
else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)
5378-
|| lookup_script(var_start, varlen) == OK
5379-
|| (import = find_imported(var_start, varlen, cctx))
5380-
!= NULL)
5377+
else
53815378
{
5382-
char_u *rawname = name + (name[1] == ':' ? 2 : 0);
5383-
5384-
if (is_decl)
5379+
int script_namespace = varlen > 1
5380+
&& STRNCMP(var_start, "s:", 2) == 0;
5381+
int script_var = (script_namespace
5382+
? lookup_script(var_start + 2, varlen - 2)
5383+
: lookup_script(var_start, varlen)) == OK;
5384+
imported_T *import =
5385+
find_imported(var_start, varlen, cctx);
5386+
5387+
if (script_namespace || script_var || import != NULL)
53855388
{
5386-
if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0))
5387-
semsg(_("E1101: Cannot declare a script variable in a function: %s"),
5389+
char_u *rawname = name + (name[1] == ':' ? 2 : 0);
5390+
5391+
if (is_decl)
5392+
{
5393+
if (script_namespace)
5394+
semsg(_("E1101: Cannot declare a script variable in a function: %s"),
53885395
name);
5389-
else
5390-
semsg(_("E1054: Variable already declared in the script: %s"),
5396+
else
5397+
semsg(_("E1054: Variable already declared in the script: %s"),
53915398
name);
5392-
goto theend;
5393-
}
5394-
dest = dest_script;
5399+
goto theend;
5400+
}
5401+
else if (cctx->ctx_ufunc->uf_script_ctx_version
5402+
== SCRIPT_VERSION_VIM9
5403+
&& script_namespace
5404+
&& !script_var && import == NULL)
5405+
{
5406+
semsg(_(e_unknown_var), name);
5407+
goto theend;
5408+
}
5409+
5410+
dest = dest_script;
53955411

5396-
// existing script-local variables should have a type
5397-
scriptvar_sid = current_sctx.sc_sid;
5398-
if (import != NULL)
5399-
scriptvar_sid = import->imp_sid;
5400-
scriptvar_idx = get_script_item_idx(scriptvar_sid,
5412+
// existing script-local variables should have a type
5413+
scriptvar_sid = current_sctx.sc_sid;
5414+
if (import != NULL)
5415+
scriptvar_sid = import->imp_sid;
5416+
scriptvar_idx = get_script_item_idx(scriptvar_sid,
54015417
rawname, TRUE);
5402-
if (scriptvar_idx >= 0)
5403-
{
5404-
scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
5405-
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
5418+
if (scriptvar_idx >= 0)
5419+
{
5420+
scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
5421+
svar_T *sv =
5422+
((svar_T *)si->sn_var_vals.ga_data)
54065423
+ scriptvar_idx;
5407-
type = sv->sv_type;
5424+
type = sv->sv_type;
5425+
}
54085426
}
5409-
}
5410-
else if (name[1] == ':' && name[2] != NUL)
5411-
{
5412-
semsg(_("E1082: Cannot use a namespaced variable: %s"),
5427+
else if (name[1] == ':' && name[2] != NUL)
5428+
{
5429+
semsg(_("E1082: Cannot use a namespaced variable: %s"),
54135430
name);
5414-
goto theend;
5415-
}
5416-
else if (!is_decl)
5417-
{
5418-
semsg(_("E1089: unknown variable: %s"), name);
5419-
goto theend;
5431+
goto theend;
5432+
}
5433+
else if (!is_decl)
5434+
{
5435+
semsg(_(e_unknown_var), name);
5436+
goto theend;
5437+
}
54205438
}
54215439
}
54225440

0 commit comments

Comments
 (0)