Skip to content

Commit 5390099

Browse files
committed
patch 8.2.1510: using "var" in :def function may refer to legacy script var
Problem: Using "var" in a :def function may refer to a legacy Vim script variable. Solution: Require using "s:" to refer to a legacy Vim script variable. (closes #6771)
1 parent 9943b3d commit 5390099

3 files changed

Lines changed: 33 additions & 27 deletions

File tree

src/testdir/test_vim9_func.vim

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -829,30 +829,30 @@ endfunc
829829
let s:funcResult = 0
830830

831831
def FuncNoArgNoRet()
832-
funcResult = 11
832+
s:funcResult = 11
833833
enddef
834834

835835
def FuncNoArgRetNumber(): number
836-
funcResult = 22
836+
s:funcResult = 22
837837
return 1234
838838
enddef
839839

840840
def FuncNoArgRetString(): string
841-
funcResult = 45
841+
s:funcResult = 45
842842
return 'text'
843843
enddef
844844

845845
def FuncOneArgNoRet(arg: number)
846-
funcResult = arg
846+
s:funcResult = arg
847847
enddef
848848

849849
def FuncOneArgRetNumber(arg: number): number
850-
funcResult = arg
850+
s:funcResult = arg
851851
return arg
852852
enddef
853853

854854
def FuncTwoArgNoRet(one: bool, two: number)
855-
funcResult = two
855+
s:funcResult = two
856856
enddef
857857

858858
def FuncOneArgRetString(arg: string): string
@@ -865,31 +865,31 @@ enddef
865865

866866
def Test_func_type()
867867
let Ref1: func()
868-
funcResult = 0
868+
s:funcResult = 0
869869
Ref1 = FuncNoArgNoRet
870870
Ref1()
871-
assert_equal(11, funcResult)
871+
assert_equal(11, s:funcResult)
872872

873873
let Ref2: func
874-
funcResult = 0
874+
s:funcResult = 0
875875
Ref2 = FuncNoArgNoRet
876876
Ref2()
877-
assert_equal(11, funcResult)
877+
assert_equal(11, s:funcResult)
878878

879-
funcResult = 0
879+
s:funcResult = 0
880880
Ref2 = FuncOneArgNoRet
881881
Ref2(12)
882-
assert_equal(12, funcResult)
882+
assert_equal(12, s:funcResult)
883883

884-
funcResult = 0
884+
s:funcResult = 0
885885
Ref2 = FuncNoArgRetNumber
886886
assert_equal(1234, Ref2())
887-
assert_equal(22, funcResult)
887+
assert_equal(22, s:funcResult)
888888

889-
funcResult = 0
889+
s:funcResult = 0
890890
Ref2 = FuncOneArgRetNumber
891891
assert_equal(13, Ref2(13))
892-
assert_equal(13, funcResult)
892+
assert_equal(13, s:funcResult)
893893
enddef
894894

895895
def Test_repeat_return_type()

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+
1510,
757759
/**/
758760
1509,
759761
/**/

src/vim9compile.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,20 @@ lookup_arg(
260260

261261
/*
262262
* Lookup a variable in the current script.
263+
* If "vim9script" is TRUE the script must be Vim9 script. Used for "var"
264+
* without "s:".
263265
* Returns OK or FAIL.
264266
*/
265267
static int
266-
lookup_script(char_u *name, size_t len)
268+
lookup_script(char_u *name, size_t len, int vim9script)
267269
{
268270
int cc;
269271
hashtab_T *ht = &SCRIPT_VARS(current_sctx.sc_sid);
270272
dictitem_T *di;
271273

274+
if (vim9script && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version
275+
!= SCRIPT_VERSION_VIM9)
276+
return FAIL;
272277
cc = name[len];
273278
name[len] = NUL;
274279
di = find_var_in_ht(ht, 0, name, TRUE);
@@ -287,7 +292,7 @@ check_defined(char_u *p, size_t len, cctx_T *cctx)
287292
int c = p[len];
288293

289294
p[len] = NUL;
290-
if (lookup_script(p, len) == OK
295+
if (lookup_script(p, len, FALSE) == OK
291296
|| (cctx != NULL
292297
&& (lookup_local(p, len, cctx) != NULL
293298
|| lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK))
@@ -2145,15 +2150,14 @@ compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
21452150
else
21462151
{
21472152
// "var" can be script-local even without using "s:" if it
2148-
// already exists.
2149-
if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version
2150-
== SCRIPT_VERSION_VIM9
2151-
|| lookup_script(*arg, len) == OK)
2152-
res = compile_load_scriptvar(cctx, name, *arg, &end,
2153-
FALSE);
2153+
// already exists in a Vim9 script or when it's imported.
2154+
if (lookup_script(*arg, len, TRUE) == OK
2155+
|| find_imported(name, 0, cctx) != NULL)
2156+
res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE);
21542157

21552158
// When the name starts with an uppercase letter or "x:" it
21562159
// can be a user defined function.
2160+
// TODO: this is just guessing
21572161
if (res == FAIL && (ASCII_ISUPPER(*name) || name[1] == ':'))
21582162
res = generate_funcref(cctx, name);
21592163
}
@@ -4697,8 +4701,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
46974701
int script_namespace = varlen > 1
46984702
&& STRNCMP(var_start, "s:", 2) == 0;
46994703
int script_var = (script_namespace
4700-
? lookup_script(var_start + 2, varlen - 2)
4701-
: lookup_script(var_start, varlen)) == OK;
4704+
? lookup_script(var_start + 2, varlen - 2, FALSE)
4705+
: lookup_script(var_start, varlen, TRUE)) == OK;
47024706
imported_T *import =
47034707
find_imported(var_start, varlen, cctx);
47044708

@@ -6637,7 +6641,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
66376641
|| lookup_local(ea.cmd, len, &cctx) != NULL
66386642
|| lookup_arg(ea.cmd, len, NULL, NULL,
66396643
NULL, &cctx) == OK
6640-
|| lookup_script(ea.cmd, len) == OK
6644+
|| lookup_script(ea.cmd, len, FALSE) == OK
66416645
|| find_imported(ea.cmd, len, &cctx) != NULL)
66426646
{
66436647
line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);

0 commit comments

Comments
 (0)