]> granicus.if.org Git - vim/commitdiff
patch 8.2.3055: strange error for assigning to "x.key" on non-dictionary v8.2.3055
authorBram Moolenaar <Bram@vim.org>
Sat, 26 Jun 2021 13:00:59 +0000 (15:00 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 26 Jun 2021 13:00:59 +0000 (15:00 +0200)
Problem:    Strange error for assigning to "x.key" on non-dictionary.
Solution:   Add a specific error message. (closes #8451)

src/errors.h
src/eval.c
src/testdir/test_let.vim
src/testdir/test_listdict.vim
src/testdir/test_vim9_assign.vim
src/version.c

index a4dcea2c7fe238c164e8c5805d3d6d7341a0c456..00894ef21cc45a054c1591a5cd7570a3b368e9f4 100644 (file)
@@ -448,3 +448,5 @@ EXTERN char e_libsodium_decryption_failed_premature[]
        INIT(= N_("E1201: Decryption failed: pre-mature end of file!"));
 EXTERN char e_no_white_space_allowed_after_str_str[]
        INIT(= N_("E1202: No white space allowed after '%s': %s"));
+EXTERN char e_dot_can_only_be_used_on_dictionary_str[]
+       INIT(= N_("E1203: Dot can only be used on a dictionary: %s"));
index 33ea8504a269ecf95ab90ccbf06b570bad75f936..7704d46e983e82dc3e039290e9ab419e7b860061 100644 (file)
@@ -924,8 +924,14 @@ get_lval(
     lp->ll_tv = &v->di_tv;
     var1.v_type = VAR_UNKNOWN;
     var2.v_type = VAR_UNKNOWN;
-    while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
+    while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.'))
     {
+       if (*p == '.' && lp->ll_tv->v_type != VAR_DICT)
+       {
+           if (!quiet)
+               semsg(_(e_dot_can_only_be_used_on_dictionary_str), name);
+           return NULL;
+       }
        if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
                && !(lp->ll_tv->v_type == VAR_DICT)
                && !(lp->ll_tv->v_type == VAR_BLOB
index c05a4cbc20bef429d50b8e472c4f880f87f47d91..d001d0578153ededaa09b95f33447ee25a07dc1f 100644 (file)
@@ -293,7 +293,7 @@ func Test_let_errors()
   let s = "var"
   let var = 1
   call assert_fails('let var += [1,2]', 'E734:')
-  call assert_fails('let {s}.1 = 2', 'E18:')
+  call assert_fails('let {s}.1 = 2', 'E1203:')
   call assert_fails('let a[1] = 5', 'E121:')
   let l = [[1,2]]
   call assert_fails('let l[:][0] = [5]', 'E708:')
index 8351acb4103e3c9b5966fadcc20081f2559b11b1..96debd64d34271123bce56ba24d70180a9f84359 100644 (file)
@@ -294,6 +294,9 @@ func Test_dict_assign()
   let d.1 = 1
   let d._ = 2
   call assert_equal({'1': 1, '_': 2}, d)
+
+  let n = 0
+  call assert_fails('let n.key = 3', 'E1203: Dot can only be used on a dictionary: n.key = 3')
 endfunc
 
 " Function in script-local List or Dict
index 8541d11a3999ffadc5a12017f0789e89baf8bffa..230ddc50c601d1ba8ff2fe12f0cfaac18b07a12c 100644 (file)
@@ -787,6 +787,12 @@ def Test_assignment_dict()
     d.dd[0] = 0
   END
   CheckDefExecFailure(lines, 'E1148:', 2)
+
+  lines =<< trim END
+    var n: any
+    n.key = 5
+  END
+  CheckDefExecAndScriptFailure2(lines, 'E1148:', 'E1203: Dot can only be used on a dictionary: n.key = 5', 2)
 enddef
 
 def Test_assignment_local()
index 2002223e7bc8475ff88708e681052dc231e524ec..6d907d5c64e265f8efc6bc79107a06d528a22520 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3055,
 /**/
     3054,
 /**/