To: vim_dev@googlegroups.com Subject: Patch 8.2.0733 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0733 Problem: Vim9: assigning to dict or list argument does not work. Solution: Recognize an argument as assignment target. Files: src/vim9compile.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.0732/src/vim9compile.c 2020-05-10 19:10:27.968996544 +0200 --- src/vim9compile.c 2020-05-10 22:52:27.806981409 +0200 *************** *** 135,140 **** --- 135,141 ---- static char e_var_notfound[] = N_("E1001: variable not found: %s"); static char e_syntax_at[] = N_("E1002: Syntax error at %s"); + static char e_used_as_arg[] = N_("E1006: %s is used as an argument"); static void delete_def_function_contents(dfunc_T *dfunc); static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx); *************** *** 1652,1658 **** if (lookup_arg(name, len, NULL, NULL, NULL, cctx) == OK) { ! emsg_namelen(_("E1006: %s is used as an argument"), name, (int)len); return NULL; } --- 1653,1659 ---- if (lookup_arg(name, len, NULL, NULL, NULL, cctx) == OK) { ! emsg_namelen(_(e_used_as_arg), name, (int)len); return NULL; } *************** *** 4592,4597 **** --- 4593,4599 ---- type_T *type = &t_any; type_T *member_type = &t_any; lvar_T *lvar = NULL; + lvar_T arg_lvar; char_u *name; char_u *sp; int has_type = FALSE; *************** *** 4760,4765 **** --- 4762,4780 ---- } lvar = lookup_local(arg, varlen, cctx); + if (lvar == NULL + && lookup_arg(arg, varlen, + &arg_lvar.lv_idx, &arg_lvar.lv_type, + &arg_lvar.lv_from_outer, cctx) == OK) + { + if (is_decl) + { + semsg(_(e_used_as_arg), name); + goto theend; + } + arg_lvar.lv_const = 0; + lvar = &arg_lvar; + } if (lvar != NULL) { if (is_decl) *************** *** 4861,4873 **** member_type = type; if (var_end > arg + varlen) { if (is_decl) { emsg(_("E1087: cannot use an index when declaring a variable")); goto theend; } - // Something follows after the variable: "var[idx]". if (arg[varlen] == '[') { has_index = TRUE; --- 4876,4888 ---- member_type = type; if (var_end > arg + varlen) { + // Something follows after the variable: "var[idx]". if (is_decl) { emsg(_("E1087: cannot use an index when declaring a variable")); goto theend; } if (arg[varlen] == '[') { has_index = TRUE; *************** *** 4884,4889 **** --- 4899,4909 ---- goto theend; } } + else if (lvar == &arg_lvar) + { + semsg(_("E1090: Cannot assign to argument %s"), name); + goto theend; + } if (heredoc) { *************** *** 6515,6520 **** --- 6535,6542 ---- oplen = assignment_len(skipwhite(var_end), &heredoc); if (oplen > 0) { + size_t len = p - ea.cmd; + // Recognize an assignment if we recognize the variable // name: // "g:var = expr" *************** *** 6527,6536 **** if (*ea.cmd == '&' || *ea.cmd == '$' || *ea.cmd == '@' ! || ((p - ea.cmd) > 2 && ea.cmd[1] == ':') ! || lookup_local(ea.cmd, p - ea.cmd, &cctx) != NULL ! || lookup_script(ea.cmd, p - ea.cmd) == OK ! || find_imported(ea.cmd, p - ea.cmd, &cctx) != NULL) { line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx); if (line == NULL) --- 6549,6560 ---- if (*ea.cmd == '&' || *ea.cmd == '$' || *ea.cmd == '@' ! || ((len) > 2 && ea.cmd[1] == ':') ! || lookup_local(ea.cmd, len, &cctx) != NULL ! || lookup_arg(ea.cmd, len, NULL, NULL, ! NULL, &cctx) == OK ! || lookup_script(ea.cmd, len) == OK ! || find_imported(ea.cmd, len, &cctx) != NULL) { line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx); if (line == NULL) *** ../vim-8.2.0732/src/testdir/test_vim9_func.vim 2020-05-07 14:37:15.949321720 +0200 --- src/testdir/test_vim9_func.vim 2020-05-10 22:47:40.884030564 +0200 *************** *** 193,198 **** --- 193,218 ---- call delete('Xdef') enddef + def DictArg(arg: dict) + arg['key'] = 'value' + enddef + + def ListArg(arg: list) + arg[0] = 'value' + enddef + + def Test_assign_to_argument() + " works for dict and list + let d: dict = {} + DictArg(d) + assert_equal('value', d['key']) + let l: list = [] + ListArg(l) + assert_equal('value', l[0]) + + call CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef'], 'E1090:') + enddef + def Test_call_func_defined_later() call assert_equal('one', g:DefinedLater('one')) call assert_fails('call NotDefined("one")', 'E117:') *** ../vim-8.2.0732/src/version.c 2020-05-10 21:47:40.152613769 +0200 --- src/version.c 2020-05-10 22:22:53.813272452 +0200 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 733, /**/ -- From "know your smileys": :~) A man with a tape recorder up his nose /// 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 ///