From: Yegappan Lakshmanan Date: Sun, 28 Sep 2025 17:17:37 +0000 (+0000) Subject: patch 9.1.1801: Vim9: misleading error when extending dictionary X-Git-Tag: v9.1.1801^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad43d2639d4031ff1893bde763505e6d4d13a6ca;p=thirdparty%2Fvim.git patch 9.1.1801: Vim9: misleading error when extending dictionary 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 Signed-off-by: Christian Brabandt --- diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 6021148597..b7b09c9724 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -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 = {a: 1}', $'d {op} 1'], $'E734: Wrong variable type for {op}') + endfor + var lines =<< trim END + var d: dict = {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 diff --git a/src/version.c b/src/version.c index 1faf29ad3c..47d461971d 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1801, /**/ 1800, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index 91c1c0c9ed..efbea59145 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -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