To: vim_dev@googlegroups.com Subject: Patch 8.2.1949 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1949 Problem: Vim9: using extend() on null dict is silently ignored. Solution: Give an error message. Initialize a dict variable with an empty dictionary. (closes #7251) Files: src/errors.h, src/list.c, src/evalvars.c, src/testdir/test_vim9_assign.vim *** ../vim-8.2.1948/src/errors.h 2020-11-03 18:20:15.422456327 +0100 --- src/errors.h 2020-11-04 11:20:16.026584267 +0100 *************** *** 288,291 **** --- 288,295 ---- INIT(= N_("E1131: Cannot add to null blob")); EXTERN char e_missing_function_argument[] INIT(= N_("E1132: Missing function argument")); + EXTERN char e_cannot_extend_null_dict[] + INIT(= N_("E1133: Cannot extend a null dict")); + EXTERN char e_cannot_extend_null_list[] + INIT(= N_("E1134: Cannot extend a null list")); #endif *** ../vim-8.2.1948/src/list.c 2020-11-03 18:20:15.422456327 +0100 --- src/list.c 2020-11-04 11:19:47.246656349 +0100 *************** *** 2303,2311 **** int error = FALSE; l1 = argvars[0].vval.v_list; l2 = argvars[1].vval.v_list; ! if (l1 != NULL && !value_check_lock(l1->lv_lock, arg_errmsg, TRUE) ! && l2 != NULL) { if (argvars[2].v_type != VAR_UNKNOWN) { --- 2303,2315 ---- int error = FALSE; l1 = argvars[0].vval.v_list; + if (l1 == NULL) + { + emsg(_(e_cannot_extend_null_list)); + return; + } l2 = argvars[1].vval.v_list; ! if (!value_check_lock(l1->lv_lock, arg_errmsg, TRUE) && l2 != NULL) { if (argvars[2].v_type != VAR_UNKNOWN) { *************** *** 2339,2347 **** int i; d1 = argvars[0].vval.v_dict; d2 = argvars[1].vval.v_dict; ! if (d1 != NULL && !value_check_lock(d1->dv_lock, arg_errmsg, TRUE) ! && d2 != NULL) { // Check the third argument. if (argvars[2].v_type != VAR_UNKNOWN) --- 2343,2355 ---- int i; d1 = argvars[0].vval.v_dict; + if (d1 == NULL) + { + emsg(_(e_cannot_extend_null_dict)); + return; + } d2 = argvars[1].vval.v_dict; ! if (!value_check_lock(d1->dv_lock, arg_errmsg, TRUE) && d2 != NULL) { // Check the third argument. if (argvars[2].v_type != VAR_UNKNOWN) *** ../vim-8.2.1948/src/evalvars.c 2020-10-25 13:22:38.216253317 +0100 --- src/evalvars.c 2020-11-04 11:32:01.888773937 +0100 *************** *** 2553,2559 **** --- 2553,2574 ---- ret = FAIL; } else if (rettv != NULL) + { + // If a list or dict variable wasn't initialized, do it now. + if (tv->v_type == VAR_DICT && tv->vval.v_dict == NULL) + { + tv->vval.v_dict = dict_alloc(); + if (tv->vval.v_dict != NULL) + ++tv->vval.v_dict->dv_refcount; + } + else if (tv->v_type == VAR_LIST && tv->vval.v_list == NULL) + { + tv->vval.v_list = list_alloc(); + if (tv->vval.v_list != NULL) + ++tv->vval.v_list->lv_refcount; + } copy_tv(tv, rettv); + } } name[len] = cc; *** ../vim-8.2.1948/src/testdir/test_vim9_assign.vim 2020-10-19 16:07:37.193322741 +0200 --- src/testdir/test_vim9_assign.vim 2020-11-04 11:34:40.172414373 +0100 *************** *** 231,240 **** var l: list l += [123] assert_equal([123], l) ! var d: dict ! d['one'] = 1 ! assert_equal(#{one: 1}, d) END CheckScriptSuccess(lines) --- 231,244 ---- var l: list l += [123] assert_equal([123], l) + END + CheckScriptSuccess(lines) ! lines =<< trim END ! vim9script ! var list: list ! extend(list, ['x']) ! assert_equal(['x'], list) END CheckScriptSuccess(lines) *************** *** 249,254 **** --- 253,300 ---- assert_equal(['a', 'b'], list) END CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + var l: list = test_null_list() + extend(l, ['x']) + assert_equal(['x'], l) + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + extend(test_null_list(), ['x']) + END + CheckScriptFailure(lines, 'E1134:', 2) + enddef + + def Test_extend_dict() + var lines =<< trim END + vim9script + var d: dict + extend(d, #{a: 1}) + assert_equal(#{a: 1}, d) + + var d2: dict + d2['one'] = 1 + assert_equal(#{one: 1}, d2) + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + var d: dict = test_null_dict() + extend(d, #{a: 'x'}) + assert_equal(#{a: 'x'}, d) + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + extend(test_null_dict(), #{a: 'x'}) + END + CheckScriptFailure(lines, 'E1133:', 2) enddef def Test_single_letter_vars() *** ../vim-8.2.1948/src/version.c 2020-11-04 11:03:08.376891850 +0100 --- src/version.c 2020-11-04 11:11:41.679830672 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 1949, /**/ -- What is the difference between a professional and an amateur? The ark was built by an amateur; professionals gave us the Titanic. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///