Patch 8.2.0675
Problem:    Vim9: no support for closures.
Solution:   Do not re-use stack entries.
Files:      src/vim9compile.c, src/ex_docmd.c, src/proto/ex_docmd.pro,
            src/evalvars.c, src/proto/evalvars.pro


*** ../vim-8.2.0674/src/vim9compile.c   2020-04-28 22:49:04.592008615 +0200
--- src/vim9compile.c   2020-05-01 15:33:54.721981415 +0200
***************
*** 97,102 ****
--- 97,103 ----
  typedef struct {
      char_u    *lv_name;
      type_T    *lv_type;
+     int               lv_idx;     // index of the variable on the stack
      int               lv_const;   // when TRUE cannot be assigned to
      int               lv_arg;     // when TRUE this is an argument
  } lvar_T;
***************
*** 112,118 ****
      garray_T  ctx_instr;          // generated instructions
  
      garray_T  ctx_locals;         // currently visible local variables
!     int               ctx_max_local;      // maximum number of locals at one 
time
  
      garray_T  ctx_imports;        // imported items
  
--- 113,119 ----
      garray_T  ctx_instr;          // generated instructions
  
      garray_T  ctx_locals;         // currently visible local variables
!     int               ctx_locals_count;   // total number of local variables
  
      garray_T  ctx_imports;        // imported items
  
***************
*** 120,125 ****
--- 121,129 ----
                                    // commands after "else"
      scope_T   *ctx_scope;         // current scope, NULL at toplevel
  
+     cctx_T    *ctx_outer;         // outer scope for lambda or nested
+                                   // function
+ 
      garray_T  ctx_type_stack;     // type of each item on the stack
      garray_T  *ctx_type_list;     // list of pointers to allocated types
  };
***************
*** 135,158 ****
  static int check_type(type_T *expected, type_T *actual, int give_msg);
  
  /*
!  * Lookup variable "name" in the local scope and return the index.
   */
!     static int
  lookup_local(char_u *name, size_t len, cctx_T *cctx)
  {
      int           idx;
  
      if (len == 0)
!       return -1;
      for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx)
      {
        lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
  
        if (STRNCMP(name, lvar->lv_name, len) == 0
                                               && STRLEN(lvar->lv_name) == len)
!           return idx;
      }
!     return -1;
  }
  
  /*
--- 139,163 ----
  static int check_type(type_T *expected, type_T *actual, int give_msg);
  
  /*
!  * Lookup variable "name" in the local scope and return it.
!  * Return NULL if not found.
   */
!     static lvar_T *
  lookup_local(char_u *name, size_t len, cctx_T *cctx)
  {
      int           idx;
  
      if (len == 0)
!       return NULL;
      for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx)
      {
        lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
  
        if (STRNCMP(name, lvar->lv_name, len) == 0
                                               && STRLEN(lvar->lv_name) == len)
!           return lvar;
      }
!     return NULL;
  }
  
  /*
***************
*** 217,223 ****
  {
      if (lookup_script(p, len) == OK
            || (cctx != NULL
!               && (lookup_local(p, len, cctx) >= 0
                    || find_imported(p, len, cctx) != NULL)))
      {
        semsg("E1073: imported name already defined: %s", p);
--- 222,228 ----
  {
      if (lookup_script(p, len) == OK
            || (cctx != NULL
!               && (lookup_local(p, len, cctx) != NULL
                    || find_imported(p, len, cctx) != NULL)))
      {
        semsg("E1073: imported name already defined: %s", p);
***************
*** 1458,1490 ****
  
  /*
   * Reserve space for a local variable.
!  * Return the index or -1 if it failed.
   */
!     static int
  reserve_local(cctx_T *cctx, char_u *name, size_t len, int isConst, type_T 
*type)
  {
-     int           idx;
      lvar_T  *lvar;
  
      if (lookup_arg(name, len, cctx) >= 0 || lookup_vararg(name, len, cctx))
      {
        emsg_namelen(_("E1006: %s is used as an argument"), name, (int)len);
!       return -1;
      }
  
      if (ga_grow(&cctx->ctx_locals, 1) == FAIL)
!       return -1;
!     idx = cctx->ctx_locals.ga_len;
!     if (cctx->ctx_max_local < idx + 1)
!       cctx->ctx_max_local = idx + 1;
!     ++cctx->ctx_locals.ga_len;
  
-     lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
      lvar->lv_name = vim_strnsave(name, (int)(len == 0 ? STRLEN(name) : len));
      lvar->lv_const = isConst;
      lvar->lv_type = type;
  
!     return idx;
  }
  
  /*
--- 1463,1496 ----
  
  /*
   * Reserve space for a local variable.
!  * Return the variable or NULL if it failed.
   */
!     static lvar_T *
  reserve_local(cctx_T *cctx, char_u *name, size_t len, int isConst, type_T 
*type)
  {
      lvar_T  *lvar;
  
      if (lookup_arg(name, len, cctx) >= 0 || lookup_vararg(name, len, cctx))
      {
        emsg_namelen(_("E1006: %s is used as an argument"), name, (int)len);
!       return NULL;
      }
  
      if (ga_grow(&cctx->ctx_locals, 1) == FAIL)
!       return NULL;
!     lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + cctx->ctx_locals.ga_len++;
! 
!     // Every local variable uses the next entry on the stack.  We could re-use
!     // the last ones when leaving a scope, but then variables used in a 
closure
!     // might get overwritten.  To keep things simple do not re-use stack
!     // entries.  This is less efficient, but memory is cheap these days.
!     lvar->lv_idx = cctx->ctx_locals_count++;
  
      lvar->lv_name = vim_strnsave(name, (int)(len == 0 ? STRLEN(name) : len));
      lvar->lv_const = isConst;
      lvar->lv_type = type;
  
!     return lvar;
  }
  
  /*
***************
*** 1511,1517 ****
   * Free all local variables.
   */
      static void
! free_local(cctx_T *cctx)
  {
      unwind_locals(cctx, 0);
      ga_clear(&cctx->ctx_locals);
--- 1517,1523 ----
   * Free all local variables.
   */
      static void
! free_locals(cctx_T *cctx)
  {
      unwind_locals(cctx, 0);
      ga_clear(&cctx->ctx_locals);
***************
*** 2331,2340 ****
        }
        else
        {
!           idx = lookup_local(*arg, len, cctx);
!           if (idx >= 0)
            {
!               type = (((lvar_T *)cctx->ctx_locals.ga_data) + idx)->lv_type;
                gen_load = TRUE;
            }
            else
--- 2337,2348 ----
        }
        else
        {
!           lvar_T *lvar = lookup_local(*arg, len, cctx);
! 
!           if (lvar != NULL)
            {
!               type = lvar->lv_type;
!               idx = lvar->lv_idx;
                gen_load = TRUE;
            }
            else
***************
*** 4040,4046 ****
      int               semicolon = 0;
      size_t    varlen;
      garray_T  *instr = &cctx->ctx_instr;
-     int               idx = -1;
      int               new_local = FALSE;
      char_u    *op;
      int               opt_type;
--- 4048,4053 ----
***************
*** 4050,4056 ****
      int               oplen = 0;
      int               heredoc = FALSE;
      type_T    *type = &t_any;
!     lvar_T    *lvar;
      char_u    *name;
      char_u    *sp;
      int               has_type = FALSE;
--- 4057,4063 ----
      int               oplen = 0;
      int               heredoc = FALSE;
      type_T    *type = &t_any;
!     lvar_T    *lvar = NULL;
      char_u    *name;
      char_u    *sp;
      int               has_type = FALSE;
***************
*** 4203,4208 ****
--- 4210,4217 ----
        }
        else
        {
+           int idx;
+ 
            for (idx = 0; reserved[idx] != NULL; ++idx)
                if (STRCMP(reserved[idx], name) == 0)
                {
***************
*** 4210,4217 ****
                    goto theend;
                }
  
!           idx = lookup_local(arg, varlen, cctx);
!           if (idx >= 0)
            {
                if (is_decl)
                {
--- 4219,4226 ----
                    goto theend;
                }
  
!           lvar = lookup_local(arg, varlen, cctx);
!           if (lvar != NULL)
            {
                if (is_decl)
                {
***************
*** 4220,4229 ****
                }
                else
                {
-                   lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
                    if (lvar->lv_const)
                    {
!                       semsg(_("E1018: Cannot assign to a constant: %s"), 
name);
                        goto theend;
                    }
                }
--- 4229,4238 ----
                }
                else
                {
                    if (lvar->lv_const)
                    {
!                       semsg(_("E1018: Cannot assign to a constant: %s"),
!                                                                        name);
                        goto theend;
                    }
                }
***************
*** 4262,4272 ****
            type = parse_type(&p, cctx->ctx_type_list);
            has_type = TRUE;
        }
!       else if (idx >= 0)
!       {
!           lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
            type = lvar->lv_type;
-       }
      }
  
      sp = p;
--- 4271,4278 ----
            type = parse_type(&p, cctx->ctx_type_list);
            has_type = TRUE;
        }
!       else if (lvar != NULL)
            type = lvar->lv_type;
      }
  
      sp = p;
***************
*** 4288,4294 ****
        goto theend;
      }
  
!     if (idx < 0 && dest == dest_local && cctx->ctx_skip != TRUE)
      {
        if (oplen > 1 && !heredoc)
        {
--- 4294,4300 ----
        goto theend;
      }
  
!     if (lvar == NULL && dest == dest_local && cctx->ctx_skip != TRUE)
      {
        if (oplen > 1 && !heredoc)
        {
***************
*** 4301,4308 ****
        // new local variable
        if (type->tt_type == VAR_FUNC && var_check_func_name(name, TRUE))
            goto theend;
!       idx = reserve_local(cctx, arg, varlen, cmdidx == CMD_const, type);
!       if (idx < 0)
            goto theend;
        new_local = TRUE;
      }
--- 4307,4314 ----
        // new local variable
        if (type->tt_type == VAR_FUNC && var_check_func_name(name, TRUE))
            goto theend;
!       lvar = reserve_local(cctx, arg, varlen, cmdidx == CMD_const, type);
!       if (lvar == NULL)
            goto theend;
        new_local = TRUE;
      }
***************
*** 4370,4376 ****
                    generate_LOADV(cctx, name + 2, TRUE);
                    break;
                case dest_local:
!                   generate_LOAD(cctx, ISN_LOAD, idx, NULL, type);
                    break;
            }
        }
--- 4376,4382 ----
                    generate_LOADV(cctx, name + 2, TRUE);
                    break;
                case dest_local:
!                   generate_LOAD(cctx, ISN_LOAD, lvar->lv_idx, NULL, type);
                    break;
            }
        }
***************
*** 4392,4400 ****
            stack = &cctx->ctx_type_stack;
            stacktype = stack->ga_len == 0 ? &t_void
                              : ((type_T **)stack->ga_data)[stack->ga_len - 1];
!           if (idx >= 0 && (is_decl || !has_type))
            {
-               lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
                if (new_local && !has_type)
                {
                    if (stacktype->tt_type == VAR_VOID)
--- 4398,4405 ----
            stack = &cctx->ctx_type_stack;
            stacktype = stack->ga_len == 0 ? &t_void
                              : ((type_T **)stack->ga_data)[stack->ga_len - 1];
!           if (lvar != NULL && (is_decl || !has_type))
            {
                if (new_local && !has_type)
                {
                    if (stacktype->tt_type == VAR_VOID)
***************
*** 4546,4551 ****
--- 4551,4557 ----
                char_u      *rawname = name + (name[1] == ':' ? 2 : 0);
                imported_T  *import = NULL;
                int         sid = current_sctx.sc_sid;
+               int         idx;
  
                if (name[1] != ':')
                {
***************
*** 4581,4586 ****
--- 4587,4593 ----
            }
            break;
        case dest_local:
+           if (lvar != NULL)
            {
                isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
  
***************
*** 4593,4605 ****
                    garray_T    *stack = &cctx->ctx_type_stack;
  
                    isn->isn_type = ISN_STORENR;
!                   isn->isn_arg.storenr.stnr_idx = idx;
                    isn->isn_arg.storenr.stnr_val = val;
                    if (stack->ga_len > 0)
                        --stack->ga_len;
                }
                else
!                   generate_STORE(cctx, ISN_STORE, idx, NULL);
            }
            break;
      }
--- 4600,4612 ----
                    garray_T    *stack = &cctx->ctx_type_stack;
  
                    isn->isn_type = ISN_STORENR;
!                   isn->isn_arg.storenr.stnr_idx = lvar->lv_idx;
                    isn->isn_arg.storenr.stnr_val = val;
                    if (stack->ga_len > 0)
                        --stack->ga_len;
                }
                else
!                   generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
            }
            break;
      }
***************
*** 5283,5290 ****
      garray_T  *instr = &cctx->ctx_instr;
      garray_T  *stack = &cctx->ctx_type_stack;
      scope_T   *scope;
!     int               loop_idx;       // index of loop iteration variable
!     int               var_idx;        // index of "var"
      type_T    *vartype;
  
      // TODO: list of variables: "for [key, value] in dict"
--- 5290,5297 ----
      garray_T  *instr = &cctx->ctx_instr;
      garray_T  *stack = &cctx->ctx_type_stack;
      scope_T   *scope;
!     lvar_T    *loop_lvar;     // loop iteration variable
!     lvar_T    *var_lvar;      // variable for "var"
      type_T    *vartype;
  
      // TODO: list of variables: "for [key, value] in dict"
***************
*** 5292,5299 ****
      for (p = arg; eval_isnamec1(*p); ++p)
        ;
      varlen = p - arg;
!     var_idx = lookup_local(arg, varlen, cctx);
!     if (var_idx >= 0)
      {
        semsg(_("E1023: variable already defined: %s"), arg);
        return NULL;
--- 5299,5306 ----
      for (p = arg; eval_isnamec1(*p); ++p)
        ;
      varlen = p - arg;
!     var_lvar = lookup_local(arg, varlen, cctx);
!     if (var_lvar != NULL)
      {
        semsg(_("E1023: variable already defined: %s"), arg);
        return NULL;
***************
*** 5314,5336 ****
        return NULL;
  
      // Reserve a variable to store the loop iteration counter.
!     loop_idx = reserve_local(cctx, (char_u *)"", 0, FALSE, &t_number);
!     if (loop_idx < 0)
      {
!       // only happens when out of memory
        drop_scope(cctx);
        return NULL;
      }
  
      // Reserve a variable to store "var"
!     var_idx = reserve_local(cctx, arg, varlen, FALSE, &t_any);
!     if (var_idx < 0)
      {
        drop_scope(cctx);
        return NULL;
      }
  
!     generate_STORENR(cctx, loop_idx, -1);
  
      // compile "expr", it remains on the stack until "endfor"
      arg = p;
--- 5321,5344 ----
        return NULL;
  
      // Reserve a variable to store the loop iteration counter.
!     loop_lvar = reserve_local(cctx, (char_u *)"", 0, FALSE, &t_number);
!     if (loop_lvar == NULL)
      {
!       // out of memory
        drop_scope(cctx);
        return NULL;
      }
  
      // Reserve a variable to store "var"
!     var_lvar = reserve_local(cctx, arg, varlen, FALSE, &t_any);
!     if (var_lvar == NULL)
      {
+       // out of memory or used as an argument
        drop_scope(cctx);
        return NULL;
      }
  
!     generate_STORENR(cctx, loop_lvar->lv_idx, -1);
  
      // compile "expr", it remains on the stack until "endfor"
      arg = p;
***************
*** 5349,5365 ****
        return NULL;
      }
      if (vartype->tt_member->tt_type != VAR_ANY)
!     {
!       lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + var_idx;
! 
!       lvar->lv_type = vartype->tt_member;
!     }
  
      // "for_end" is set when ":endfor" is found
      scope->se_u.se_for.fs_top_label = instr->ga_len;
  
!     generate_FOR(cctx, loop_idx);
!     generate_STORE(cctx, ISN_STORE, var_idx, NULL);
  
      return arg;
  }
--- 5357,5369 ----
        return NULL;
      }
      if (vartype->tt_member->tt_type != VAR_ANY)
!       var_lvar->lv_type = vartype->tt_member;
  
      // "for_end" is set when ":endfor" is found
      scope->se_u.se_for.fs_top_label = instr->ga_len;
  
!     generate_FOR(cctx, loop_lvar->lv_idx);
!     generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
  
      return arg;
  }
***************
*** 6158,6164 ****
                            || *ea.cmd == '$'
                            || *ea.cmd == '@'
                            || ((p - ea.cmd) > 2 && ea.cmd[1] == ':')
!                           || lookup_local(ea.cmd, p - ea.cmd, &cctx) >= 0
                            || lookup_script(ea.cmd, p - ea.cmd) == OK
                            || find_imported(ea.cmd, p - ea.cmd, &cctx) != NULL)
                    {
--- 6162,6168 ----
                            || *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)
                    {
***************
*** 6175,6181 ****
         * COMMAND after range
         */
        ea.cmd = skip_range(ea.cmd, NULL);
!       p = find_ex_command(&ea, NULL, is_ex_command ? NULL : lookup_local,
                                                                        &cctx);
  
        if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
--- 6179,6186 ----
         * COMMAND after range
         */
        ea.cmd = skip_range(ea.cmd, NULL);
!       p = find_ex_command(&ea, NULL, is_ex_command ? NULL
!                  : (void *(*)(char_u *, size_t, cctx_T *))lookup_local,
                                                                        &cctx);
  
        if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
***************
*** 6349,6355 ****
        dfunc->df_deleted = FALSE;
        dfunc->df_instr = instr->ga_data;
        dfunc->df_instr_count = instr->ga_len;
!       dfunc->df_varcount = cctx.ctx_max_local;
      }
  
      {
--- 6354,6360 ----
        dfunc->df_deleted = FALSE;
        dfunc->df_instr = instr->ga_data;
        dfunc->df_instr_count = instr->ga_len;
!       dfunc->df_varcount = cctx.ctx_locals_count;
      }
  
      {
***************
*** 6431,6437 ****
  
      current_sctx = save_current_sctx;
      free_imported(&cctx);
!     free_local(&cctx);
      ga_clear(&cctx.ctx_type_stack);
  }
  
--- 6436,6442 ----
  
      current_sctx = save_current_sctx;
      free_imported(&cctx);
!     free_locals(&cctx);
      ga_clear(&cctx.ctx_type_stack);
  }
  
*** ../vim-8.2.0674/src/ex_docmd.c      2020-04-30 22:29:36.622024155 +0200
--- src/ex_docmd.c      2020-05-01 15:30:01.390841317 +0200
***************
*** 3157,3163 ****
  find_ex_command(
        exarg_T *eap,
        int     *full UNUSED,
!       int     (*lookup)(char_u *, size_t, cctx_T *) UNUSED,
        cctx_T  *cctx UNUSED)
  {
      int               len;
--- 3157,3163 ----
  find_ex_command(
        exarg_T *eap,
        int     *full UNUSED,
!       void    *(*lookup)(char_u *, size_t, cctx_T *) UNUSED,
        cctx_T  *cctx UNUSED)
  {
      int               len;
***************
*** 3197,3203 ****
            // "g:var = expr"
            // "var = expr"  where "var" is a local var name.
            if (((p - eap->cmd) > 2 && eap->cmd[1] == ':')
!                   || lookup(eap->cmd, p - eap->cmd, cctx) >= 0)
            {
                eap->cmdidx = CMD_let;
                return eap->cmd;
--- 3197,3203 ----
            // "g:var = expr"
            // "var = expr"  where "var" is a local var name.
            if (((p - eap->cmd) > 2 && eap->cmd[1] == ':')
!                   || lookup(eap->cmd, p - eap->cmd, cctx) != NULL)
            {
                eap->cmdidx = CMD_let;
                return eap->cmd;
*** ../vim-8.2.0674/src/proto/ex_docmd.pro      2020-04-16 22:10:42.656733692 
+0200
--- src/proto/ex_docmd.pro      2020-05-01 15:27:47.867333219 +0200
***************
*** 7,13 ****
  int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only);
  int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
  int checkforcmd(char_u **pp, char *cmd, int len);
! char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, 
size_t, cctx_T *), cctx_T *cctx);
  int modifier_len(char_u *cmd);
  int cmd_exists(char_u *name);
  cmdidx_T excmd_get_cmdidx(char_u *cmd, int len);
--- 7,13 ----
  int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only);
  int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
  int checkforcmd(char_u **pp, char *cmd, int len);
! char_u *find_ex_command(exarg_T *eap, int *full, void *((*lookup)(char_u *, 
size_t, cctx_T *)), cctx_T *cctx);
  int modifier_len(char_u *cmd);
  int cmd_exists(char_u *name);
  cmdidx_T excmd_get_cmdidx(char_u *cmd, int len);
***************
*** 19,25 ****
  char_u *skip_cmd_arg(char_u *p, int rembs);
  int get_bad_opt(char_u *p, exarg_T *eap);
  int ends_excmd(int c);
! int ends_excmd2(char_u *before, char_u *cmd);
  char_u *find_nextcmd(char_u *p);
  char_u *check_nextcmd(char_u *p);
  char_u *get_command_name(expand_T *xp, int idx);
--- 19,25 ----
  char_u *skip_cmd_arg(char_u *p, int rembs);
  int get_bad_opt(char_u *p, exarg_T *eap);
  int ends_excmd(int c);
! int ends_excmd2(char_u *cmd_start, char_u *cmd);
  char_u *find_nextcmd(char_u *p);
  char_u *check_nextcmd(char_u *p);
  char_u *get_command_name(expand_T *xp, int idx);
*** ../vim-8.2.0674/src/evalvars.c      2020-05-01 14:10:10.188390740 +0200
--- src/evalvars.c      2020-05-01 15:25:42.127796319 +0200
***************
*** 2495,2513 ****
  
  /*
   * Look for "name[len]" in script-local variables.
!  * Return -1 when not found.
   */
!     int
  lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy UNUSED)
  {
      hashtab_T *ht = get_script_local_ht();
      char_u    buffer[30];
      char_u    *p;
!     int               res;
      hashitem_T        *hi;
  
      if (ht == NULL)
!       return -1;
      if (len < sizeof(buffer) - 1)
      {
        vim_strncpy(buffer, name, len);
--- 2495,2513 ----
  
  /*
   * Look for "name[len]" in script-local variables.
!  * Return a non-NULL pointer when found, NULL when not found.
   */
!     void *
  lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy UNUSED)
  {
      hashtab_T *ht = get_script_local_ht();
      char_u    buffer[30];
      char_u    *p;
!     void      *res;
      hashitem_T        *hi;
  
      if (ht == NULL)
!       return NULL;
      if (len < sizeof(buffer) - 1)
      {
        vim_strncpy(buffer, name, len);
***************
*** 2517,2531 ****
      {
        p = vim_strnsave(name, (int)len);
        if (p == NULL)
!           return -1;
      }
  
      hi = hash_find(ht, p);
!     res = HASHITEM_EMPTY(hi) ? -1 : 1;
  
      // if not script-local, then perhaps imported
!     if (res == -1 && find_imported(p, 0, NULL) != NULL)
!       res = 1;
  
      if (p != buffer)
        vim_free(p);
--- 2517,2531 ----
      {
        p = vim_strnsave(name, (int)len);
        if (p == NULL)
!           return NULL;
      }
  
      hi = hash_find(ht, p);
!     res = HASHITEM_EMPTY(hi) ? NULL : hi;
  
      // if not script-local, then perhaps imported
!     if (res == NULL && find_imported(p, 0, NULL) != NULL)
!       res = p;
  
      if (p != buffer)
        vim_free(p);
*** ../vim-8.2.0674/src/proto/evalvars.pro      2020-04-19 16:28:55.296495996 
+0200
--- src/proto/evalvars.pro      2020-05-01 15:25:08.939918638 +0200
***************
*** 55,61 ****
  void check_vars(char_u *name, int len);
  dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
  dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int 
no_autoload);
! int lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy);
  hashtab_T *find_var_ht(char_u *name, char_u **varname);
  char_u *get_var_value(char_u *name);
  void new_script_vars(scid_T id);
--- 55,61 ----
  void check_vars(char_u *name, int len);
  dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
  dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int 
no_autoload);
! void *lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy);
  hashtab_T *find_var_ht(char_u *name, char_u **varname);
  char_u *get_var_value(char_u *name);
  void new_script_vars(scid_T id);
*** ../vim-8.2.0674/src/version.c       2020-05-01 14:26:17.132949262 +0200
--- src/version.c       2020-05-01 15:42:04.808364746 +0200
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     675,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
36. You miss more than five meals a week downloading the latest games from
    Apogee.

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202005011344.041DivUd008029%40masaka.moolenaar.net.

Raspunde prin e-mail lui