]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1801: Vim9: misleading error when extending dictionary v9.1.1801
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sun, 28 Sep 2025 17:17:37 +0000 (17:17 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 28 Sep 2025 17:17:37 +0000 (17:17 +0000)
Problem:  Vim9: misleading error when extending dictionary
          (lacygoill)
Solution: Give a proper error message when a Dict type is used with a
          compound operator (Yegappan Lakshmanan)

fixes: #8072
closes: #18426

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/test_vim9_assign.vim
src/version.c
src/vim9compile.c

index 6021148597e8c88c8fc2f4069eb29cee93bdabe4..b7b09c972424c85aaeceaba6550d8724a8c2106c 100644 (file)
@@ -3414,6 +3414,19 @@ def Test_type_check()
   v9.CheckScriptFailure(lines, 'E1411: Missing dot after object "o"')
 enddef
 
+" Test for using a compound operator with a dict
+def Test_dict_compoundop_check()
+  for op in ['+=', '-=', '*=', '/=', '%=']
+    v9.CheckSourceDefAndScriptFailure(['var d: dict<number> = {a: 1}', $'d {op} 1'], $'E734: Wrong variable type for {op}')
+  endfor
+  var lines =<< trim END
+    var d: dict<number> = {a: 1}
+    d['a'] += 2
+    assert_equal({a: 3}, d)
+  END
+  v9.CheckSourceDefAndScriptSuccess(lines)
+enddef
+
 " Test for checking the argument type of a def function
 def Test_func_argtype_check()
   var lines =<< trim END
index 1faf29ad3cbeab95b1b79ae89481d5afd93846df..47d461971d2117e62421448f6a5f566ea26ce1bb 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1801,
 /**/
     1800,
 /**/
index 91c1c0c9ed2c5f783b5c0471b100726280f9313a..efbea59145ac437cd41f6e3907fcb930f78abea6 100644 (file)
@@ -3439,26 +3439,41 @@ compile_assign_rhs(cctx_T *cctx, cac_T *cac)
 }
 
 /*
- * Compile a compound op assignment statement (+=, -=, *=, %=, etc.)
+ * Returns OK if "type" supports compound operator "op_arg" (e.g. +=, -=, %=,
+ * etc.).  Compound operators are not supported with a tuple and a dict.
+ * Returns FAIL if compound operator is not supported.
  */
     static int
-compile_assign_compound_op(cctx_T *cctx, cac_T *cac)
+check_type_supports_compound_op(type_T *type, char_u op_arg)
 {
-    lhs_T          *lhs = &cac->cac_lhs;
-    type_T         *expected;
-    type_T         *stacktype = NULL;
-
-    if (cac->cac_lhs.lhs_type->tt_type == VAR_TUPLE)
+    if (type->tt_type == VAR_TUPLE || type->tt_type == VAR_DICT)
     {
-       // compound operators are not supported with a tuple
        char_u  op[2];
 
-       op[0] = *cac->cac_op;
+       op[0] = op_arg;
        op[1] = NUL;
        semsg(_(e_wrong_variable_type_for_str_equal), op);
        return FAIL;
     }
 
+    return OK;
+}
+
+/*
+ * Compile a compound op assignment statement (+=, -=, *=, %=, etc.)
+ */
+    static int
+compile_assign_compound_op(cctx_T *cctx, cac_T *cac)
+{
+    lhs_T          *lhs = &cac->cac_lhs;
+    type_T         *expected;
+    type_T         *stacktype = NULL;
+
+    if (cac->cac_lhs.lhs_type->tt_type == VAR_TUPLE
+           && check_type_supports_compound_op(cac->cac_lhs.lhs_type,
+                                                       *cac->cac_op) == FAIL)
+       return FAIL;
+
     if (*cac->cac_op == '.')
     {
        expected = lhs->lhs_member_type;
@@ -3474,6 +3489,10 @@ compile_assign_compound_op(cctx_T *cctx, cac_T *cac)
     {
        expected = lhs->lhs_member_type;
        stacktype = get_type_on_stack(cctx, 0);
+
+       if (check_type_supports_compound_op(expected, *cac->cac_op) == FAIL)
+           return FAIL;
+
        if (
                // If variable is float operation with number is OK.
                !(expected == &t_float && (stacktype == &t_number