# HG changeset patch # User Bram Moolenaar # Date 1563650104 -7200 # Node ID f8cd168384346d0312679ca94c847685a6dc6318 # Parent c8bdaff91140940c7a3daf020778eb2e58a036a3 patch 8.1.1722: error when scriptversion is 2 a making a dictionary access commit https://github.com/vim/vim/commit/61343f0c44c8e71df04918d033e0a744c0b7f8aa Author: Bram Moolenaar Date: Sat Jul 20 21:11:13 2019 +0200 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) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -1486,7 +1486,7 @@ ex_let_const(exarg_T *eap, int is_const) /* * Assign the typevalue "tv" to the variable or variables at "arg_start". * Handles both "var" with any type and "[var, var; var]" with a list type. - * When "nextchars" is not NULL it points to a string with characters that + * When "op" is not NULL it points to a string with characters that * must appear after the variable(s). Use "+", "-" or "." for add, subtract * or concatenate. * Returns OK or FAIL; @@ -1499,7 +1499,7 @@ ex_let_vars( int semicolon, // from skip_var_list() int var_count, // from skip_var_list() int is_const, // lock variables for const - char_u *nextchars) + char_u *op) { char_u *arg = arg_start; list_T *l; @@ -1512,7 +1512,7 @@ ex_let_vars( /* * ":let var = expr" or ":for var in list" */ - if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL) + if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) return FAIL; return OK; } @@ -1543,7 +1543,7 @@ ex_let_vars( { arg = skipwhite(arg + 1); arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, - (char_u *)",;]", nextchars); + (char_u *)",;]", op); item = item->li_next; if (arg == NULL) return FAIL; @@ -1568,7 +1568,7 @@ ex_let_vars( l->lv_refcount = 1; arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, - (char_u *)"]", nextchars); + (char_u *)"]", op); clear_tv(<v); if (arg == NULL) return FAIL; @@ -7355,9 +7355,14 @@ handle_subscript( int len; typval_T functv; + // "." is ".name" lookup when we found a dict or when evaluating and + // scriptversion is at least 2, where string concatenation is "..". while (ret == OK && (**arg == '[' - || (**arg == '.' && rettv->v_type == VAR_DICT) + || (**arg == '.' && (rettv->v_type == VAR_DICT + || (!evaluate + && (*arg)[1] != '.' + && current_sctx.sc_version >= 2))) || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL))) && !VIM_ISWHITE(*(*arg - 1))) diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim --- a/src/testdir/test_eval_stuff.vim +++ b/src/testdir/test_eval_stuff.vim @@ -176,6 +176,13 @@ func Test_vvar_scriptversion2() call assert_true(v:versionlong > 8011525) endfunc +func Test_dict_access_scriptversion2() + let l:x = {'foo': 1} + + call assert_false(0 && l:x.foo) + call assert_true(1 && l:x.foo) +endfunc + func Test_scriptversion() call writefile(['scriptversion 9'], 'Xversionscript') call assert_fails('source Xversionscript', 'E999:') diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -778,6 +778,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1722, +/**/ 1721, /**/ 1720,