Skip to content

Commit 2ef951d

Browse files
committed
patch 8.2.2290: Vim9: unlet of global variable cannot be compiled
Problem: Vim9: unlet of global variable cannot be compiled. Solution: Skip over variables that might be defined later. Give an error if a subscript is found. (closes #7585)
1 parent e5a2dc8 commit 2ef951d

5 files changed

Lines changed: 26 additions & 3 deletions

File tree

src/eval.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -813,9 +813,9 @@ get_lval(
813813
// Clear everything in "lp".
814814
CLEAR_POINTER(lp);
815815

816-
if (skip)
816+
if (skip || (flags & GLV_COMPILING))
817817
{
818-
// When skipping just find the end of the name.
818+
// When skipping or compiling just find the end of the name.
819819
lp->ll_name = name;
820820
lp->ll_name_end = find_name_end(name, NULL, NULL,
821821
FNE_INCL_BR | fne_flags);

src/testdir/test_vim9_assign.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,15 @@ def Test_unlet()
13401340
assert_false(exists('s:somevar'))
13411341
unlet! s:somevar
13421342

1343+
# can compile unlet before variable exists
1344+
# This doesn't work yet
1345+
#g:someDict = {key: 'val'}
1346+
#var k = 'key'
1347+
#unlet g:someDict[k]
1348+
#assert_equal({}, g:someDict)
1349+
#unlet g:someDict
1350+
#assert_false(exists('g:someDict'))
1351+
13431352
CheckScriptFailure([
13441353
'vim9script',
13451354
'var svar = 123',

src/version.c

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

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2290,
753755
/**/
754756
2289,
755757
/**/

src/vim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2544,12 +2544,14 @@ typedef enum {
25442544
#define TFN_NO_DEREF 0x08 // do not dereference a Funcref
25452545
#define TFN_READ_ONLY 0x10 // will not change the var
25462546
#define TFN_NO_DECL 0x20 // only used for GLV_NO_DECL
2547+
#define TFN_COMPILING 0x40 // only used for GLV_COMPILING
25472548

25482549
// Values for get_lval() flags argument:
25492550
#define GLV_QUIET TFN_QUIET // no error messages
25502551
#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD // do not use script autoloading
25512552
#define GLV_READ_ONLY TFN_READ_ONLY // will not change the var
25522553
#define GLV_NO_DECL TFN_NO_DECL // assignment without :var or :let
2554+
#define GLV_COMPILING TFN_COMPILING // variable may be defined later
25532555

25542556
#define DO_NOT_FREE_CNT 99999 // refcount for dict or list that should not
25552557
// be freed.

src/vim9compile.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6130,6 +6130,12 @@ compile_unlet(
61306130

61316131
// Normal name. Only supports g:, w:, t: and b: namespaces.
61326132
*name_end = NUL;
6133+
if (vim_strchr(p, '.') != NULL || vim_strchr(p, '[') != NULL)
6134+
{
6135+
*name_end = cc;
6136+
goto failed;
6137+
}
6138+
61336139
if (*p == '$')
61346140
ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit);
61356141
else if (check_vim9_unlet(p) == FAIL)
@@ -6141,8 +6147,11 @@ compile_unlet(
61416147
return ret;
61426148
}
61436149

6150+
failed:
61446151
// TODO: unlet {list}[idx]
61456152
// TODO: unlet {dict}[key]
6153+
// complication: {list} can be global while "idx" is local, thus we can't
6154+
// call ex_unlet().
61466155
emsg("Sorry, :unlet not fully implemented yet");
61476156
return FAIL;
61486157
}
@@ -6163,7 +6172,8 @@ compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
61636172
}
61646173

61656174
// TODO: this doesn't work for local variables
6166-
ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD, compile_unlet, cctx);
6175+
ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD | GLV_COMPILING,
6176+
compile_unlet, cctx);
61676177
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
61686178
}
61696179

0 commit comments

Comments
 (0)