Skip to content

Commit 61343f0

Browse files
committed
patch 8.1.1722: error when scriptversion is 2 a making a dictionary access
Problem: Error when scriptversion is 2 a making a dictionary access. Solution: Parse the subscript even when not evaluating the sub-expression. (closes #4704)
1 parent 63187f7 commit 61343f0

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

src/eval.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,7 @@ ex_let_const(exarg_T *eap, int is_const)
14861486
/*
14871487
* Assign the typevalue "tv" to the variable or variables at "arg_start".
14881488
* Handles both "var" with any type and "[var, var; var]" with a list type.
1489-
* When "nextchars" is not NULL it points to a string with characters that
1489+
* When "op" is not NULL it points to a string with characters that
14901490
* must appear after the variable(s). Use "+", "-" or "." for add, subtract
14911491
* or concatenate.
14921492
* Returns OK or FAIL;
@@ -1499,7 +1499,7 @@ ex_let_vars(
14991499
int semicolon, // from skip_var_list()
15001500
int var_count, // from skip_var_list()
15011501
int is_const, // lock variables for const
1502-
char_u *nextchars)
1502+
char_u *op)
15031503
{
15041504
char_u *arg = arg_start;
15051505
list_T *l;
@@ -1512,7 +1512,7 @@ ex_let_vars(
15121512
/*
15131513
* ":let var = expr" or ":for var in list"
15141514
*/
1515-
if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL)
1515+
if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL)
15161516
return FAIL;
15171517
return OK;
15181518
}
@@ -1543,7 +1543,7 @@ ex_let_vars(
15431543
{
15441544
arg = skipwhite(arg + 1);
15451545
arg = ex_let_one(arg, &item->li_tv, TRUE, is_const,
1546-
(char_u *)",;]", nextchars);
1546+
(char_u *)",;]", op);
15471547
item = item->li_next;
15481548
if (arg == NULL)
15491549
return FAIL;
@@ -1568,7 +1568,7 @@ ex_let_vars(
15681568
l->lv_refcount = 1;
15691569

15701570
arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, is_const,
1571-
(char_u *)"]", nextchars);
1571+
(char_u *)"]", op);
15721572
clear_tv(&ltv);
15731573
if (arg == NULL)
15741574
return FAIL;
@@ -7355,9 +7355,14 @@ handle_subscript(
73557355
int len;
73567356
typval_T functv;
73577357

7358+
// "." is ".name" lookup when we found a dict or when evaluating and
7359+
// scriptversion is at least 2, where string concatenation is "..".
73587360
while (ret == OK
73597361
&& (**arg == '['
7360-
|| (**arg == '.' && rettv->v_type == VAR_DICT)
7362+
|| (**arg == '.' && (rettv->v_type == VAR_DICT
7363+
|| (!evaluate
7364+
&& (*arg)[1] != '.'
7365+
&& current_sctx.sc_version >= 2)))
73617366
|| (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
73627367
|| rettv->v_type == VAR_PARTIAL)))
73637368
&& !VIM_ISWHITE(*(*arg - 1)))

src/testdir/test_eval_stuff.vim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ func Test_vvar_scriptversion2()
176176
call assert_true(v:versionlong > 8011525)
177177
endfunc
178178

179+
func Test_dict_access_scriptversion2()
180+
let l:x = {'foo': 1}
181+
182+
call assert_false(0 && l:x.foo)
183+
call assert_true(1 && l:x.foo)
184+
endfunc
185+
179186
func Test_scriptversion()
180187
call writefile(['scriptversion 9'], 'Xversionscript')
181188
call assert_fails('source Xversionscript', 'E999:')

src/version.c

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

778778
static int included_patches[] =
779779
{ /* Add new patch number below this line */
780+
/**/
781+
1722,
780782
/**/
781783
1721,
782784
/**/

0 commit comments

Comments
 (0)