Patch 8.2.2861
Problem:    Vim9: "legacy return" is not recognized as a return statement.
Solution:   Specifically check for a return command. (closes #8213)
Files:      src/vim9compile.c, src/vim9execute.c, src/vim9.h,
            src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2860/src/vim9compile.c   2021-05-16 15:24:45.654704709 +0200
--- src/vim9compile.c   2021-05-16 23:38:53.693003933 +0200
***************
*** 2174,2179 ****
--- 2174,2198 ----
  }
  
      static int
+ generate_LEGACY_EVAL(cctx_T *cctx, char_u *line)
+ {
+     isn_T     *isn;
+     garray_T  *stack = &cctx->ctx_type_stack;
+ 
+     RETURN_OK_IF_SKIP(cctx);
+     if ((isn = generate_instr(cctx, ISN_LEGACY_EVAL)) == NULL)
+       return FAIL;
+     isn->isn_arg.string = vim_strsave(line);
+ 
+     if (ga_grow(stack, 1) == FAIL)
+       return FAIL;
+     ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
+     ++stack->ga_len;
+ 
+     return OK;
+ }
+ 
+     static int
  generate_EXECCONCAT(cctx_T *cctx, int count)
  {
      isn_T     *isn;
***************
*** 5321,5330 ****
  }
  
  /*
!  * compile "return [expr]"
   */
      static char_u *
! compile_return(char_u *arg, int check_return_type, cctx_T *cctx)
  {
      char_u    *p = arg;
      garray_T  *stack = &cctx->ctx_type_stack;
--- 5340,5350 ----
  }
  
  /*
!  * Compile "return [expr]".
!  * When "legacy" is TRUE evaluate [expr] with legacy syntax
   */
      static char_u *
! compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx)
  {
      char_u    *p = arg;
      garray_T  *stack = &cctx->ctx_type_stack;
***************
*** 5332,5340 ****
  
      if (*p != NUL && *p != '|' && *p != '\n')
      {
!       // compile return argument into instructions
!       if (compile_expr0(&p, cctx) == FAIL)
!           return NULL;
  
        if (cctx->ctx_skip != SKIP_YES)
        {
--- 5352,5375 ----
  
      if (*p != NUL && *p != '|' && *p != '\n')
      {
!       if (legacy)
!       {
!           int save_flags = cmdmod.cmod_flags;
! 
!           generate_LEGACY_EVAL(cctx, p);
!           if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, -1,
!                                               0, cctx, FALSE, FALSE) == FAIL)
!               return NULL;
!           cmdmod.cmod_flags |= CMOD_LEGACY;
!           (void)skip_expr(&p, NULL);
!           cmdmod.cmod_flags = save_flags;
!       }
!       else
!       {
!           // compile return argument into instructions
!           if (compile_expr0(&p, cctx) == FAIL)
!               return NULL;
!       }
  
        if (cctx->ctx_skip != SKIP_YES)
        {
***************
*** 9193,9199 ****
  
        // When using ":legacy cmd" always use compile_exec().
        if (local_cmdmod.cmod_flags & CMOD_LEGACY)
!           ea.cmdidx = CMD_legacy;
  
        if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
        {
--- 9228,9242 ----
  
        // When using ":legacy cmd" always use compile_exec().
        if (local_cmdmod.cmod_flags & CMOD_LEGACY)
!       {
!           char_u *start = ea.cmd;
! 
!           // ":legacy return expr" needs to be handled differently.
!           if (checkforcmd(&start, "return", 4))
!               ea.cmdidx = CMD_return;
!           else
!               ea.cmdidx = CMD_legacy;
!       }
  
        if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
        {
***************
*** 9254,9260 ****
                    goto erret;
  
            case CMD_return:
!                   line = compile_return(p, check_return_type, &cctx);
                    cctx.ctx_had_return = TRUE;
                    break;
  
--- 9297,9304 ----
                    goto erret;
  
            case CMD_return:
!                   line = compile_return(p, check_return_type,
!                                local_cmdmod.cmod_flags & CMOD_LEGACY, &cctx);
                    cctx.ctx_had_return = TRUE;
                    break;
  
***************
*** 9605,9610 ****
--- 9649,9655 ----
      {
        case ISN_DEF:
        case ISN_EXEC:
+       case ISN_LEGACY_EVAL:
        case ISN_LOADAUTO:
        case ISN_LOADB:
        case ISN_LOADENV:
*** ../vim-8.2.2860/src/vim9execute.c   2021-05-16 15:24:45.654704709 +0200
--- src/vim9execute.c   2021-05-16 23:28:15.207783649 +0200
***************
*** 1388,1393 ****
--- 1388,1414 ----
                }
                break;
  
+           // Evaluate an expression with legacy syntax, push it onto the
+           // stack.
+           case ISN_LEGACY_EVAL:
+               {
+                   char_u  *arg = iptr->isn_arg.string;
+                   int     res;
+                   int     save_flags = cmdmod.cmod_flags;
+ 
+                   if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+                       return FAIL;
+                   tv = STACK_TV_BOT(0);
+                   init_tv(tv);
+                   cmdmod.cmod_flags |= CMOD_LEGACY;
+                   res = eval0(arg, tv, NULL, &EVALARG_EVALUATE);
+                   cmdmod.cmod_flags = save_flags;
+                   if (res == FAIL)
+                       goto on_error;
+                   ++ectx->ec_stack.ga_len;
+               }
+               break;
+ 
            // push typeval VAR_INSTR with instructions to be executed
            case ISN_INSTR:
                {
***************
*** 4464,4469 ****
--- 4485,4494 ----
            case ISN_EXEC:
                smsg("%s%4d EXEC %s", pfx, current, iptr->isn_arg.string);
                break;
+           case ISN_LEGACY_EVAL:
+               smsg("%s%4d EVAL legacy %s", pfx, current,
+                                                        iptr->isn_arg.string);
+               break;
            case ISN_REDIRSTART:
                smsg("%s%4d REDIR", pfx, current);
                break;
*** ../vim-8.2.2860/src/vim9.h  2021-05-07 17:55:51.963584417 +0200
--- src/vim9.h  2021-05-16 23:23:48.392946482 +0200
***************
*** 14,19 ****
--- 14,20 ----
  typedef enum {
      ISN_EXEC,     // execute Ex command line isn_arg.string
      ISN_EXECCONCAT, // execute Ex command from isn_arg.number items on stack
+     ISN_LEGACY_EVAL, // evaluate expression isn_arg.string with legacy syntax.
      ISN_ECHO,     // echo isn_arg.echo.echo_count items on top of stack
      ISN_EXECUTE,    // execute Ex commands isn_arg.number items on top of 
stack
      ISN_ECHOMSG,    // echo Ex commands isn_arg.number items on top of stack
*** ../vim-8.2.2860/src/testdir/test_vim9_expr.vim      2021-05-06 
21:04:51.518534023 +0200
--- src/testdir/test_vim9_expr.vim      2021-05-16 23:58:35.191821216 +0200
***************
*** 2777,2782 ****
--- 2777,2786 ----
    CheckDefAndScriptFailure(lines, 'E15:')
  enddef
  
+ def LegacyReturn(): string
+   legacy return #{key: 'ok'}.key
+ enddef
+ 
  def Test_expr7_legacy_script()
    var lines =<< trim END
        let s:legacy = 'legacy'
***************
*** 2790,2795 ****
--- 2794,2810 ----
        call assert_equal('legacy', GetLocalPrefix())
    END
    CheckScriptSuccess(lines)
+ 
+   assert_equal('ok', LegacyReturn())
+ 
+   lines =<< trim END
+       vim9script 
+       def GetNumber(): number   
+           legacy return range(3)->map('v:val + 1') 
+       enddef 
+       echo GetNumber()
+   END
+   CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got 
list<number>')
  enddef
  
  def Echo(arg: any): string
*** ../vim-8.2.2860/src/version.c       2021-05-16 20:18:51.029536617 +0200
--- src/version.c       2021-05-16 21:55:54.315716622 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2861,
  /**/

-- 
If I tell you "you have a beautiful body", would you hold it against me?

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/202105162202.14GM2Shs3665014%40masaka.moolenaar.net.

Raspunde prin e-mail lui