Patch 8.2.2209
Problem:    Vim9: return type of => lambda not parsed.
Solution:   Parse and use the return type.
Files:      src/vim9compile.c, src/userfunc.c, src/vim9type.c,
            src/proto/vim9type.pro, src/vim9script.c, src/eval.c
            src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2208/src/vim9compile.c   2020-12-24 21:56:37.647479568 +0100
--- src/vim9compile.c   2020-12-25 12:33:08.507858416 +0100
***************
*** 4118,4128 ****
      // Recognize <type>
      if (**arg == '<' && eval_isnamec1((*arg)[1]))
      {
-       int             called_emsg_before = called_emsg;
- 
        ++*arg;
!       want_type = parse_type(arg, cctx->ctx_type_list);
!       if (called_emsg != called_emsg_before)
            return FAIL;
  
        if (**arg != '>')
--- 4118,4126 ----
      // Recognize <type>
      if (**arg == '<' && eval_isnamec1((*arg)[1]))
      {
        ++*arg;
!       want_type = parse_type(arg, cctx->ctx_type_list, TRUE);
!       if (want_type == NULL)
            return FAIL;
  
        if (**arg != '>')
***************
*** 4809,4815 ****
   * compile "return [expr]"
   */
      static char_u *
! compile_return(char_u *arg, int set_return_type, cctx_T *cctx)
  {
      char_u    *p = arg;
      garray_T  *stack = &cctx->ctx_type_stack;
--- 4807,4813 ----
   * 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;
***************
*** 4824,4831 ****
        if (cctx->ctx_skip != SKIP_YES)
        {
            stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!           if (set_return_type)
                cctx->ctx_ufunc->uf_ret_type = stack_type;
            else
            {
                if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID
--- 4822,4831 ----
        if (cctx->ctx_skip != SKIP_YES)
        {
            stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!           if (check_return_type && cctx->ctx_ufunc->uf_ret_type == NULL)
!           {
                cctx->ctx_ufunc->uf_ret_type = stack_type;
+           }
            else
            {
                if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID
***************
*** 4843,4849 ****
      }
      else
      {
!       // "set_return_type" cannot be TRUE, only used for a lambda which
        // always has an argument.
        if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID
                && cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN)
--- 4843,4849 ----
      }
      else
      {
!       // "check_return_type" cannot be TRUE, only used for a lambda which
        // always has an argument.
        if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID
                && cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN)
***************
*** 5636,5642 ****
                    goto theend;
                }
                p = skipwhite(var_end + 1);
!               type = parse_type(&p, cctx->ctx_type_list);
                has_type = TRUE;
            }
            else if (lvar != NULL)
--- 5636,5644 ----
                    goto theend;
                }
                p = skipwhite(var_end + 1);
!               type = parse_type(&p, cctx->ctx_type_list, TRUE);
!               if (type == NULL)
!                   goto theend;
                has_type = TRUE;
            }
            else if (lvar != NULL)
***************
*** 7417,7431 ****
   * After ex_function() has collected all the function lines: parse and compile
   * the lines into instructions.
   * Adds the function to "def_functions".
!  * When "set_return_type" is set then set ufunc->uf_ret_type to the type of 
the
!  * return statement (used for lambda).
   * "outer_cctx" is set for a nested function.
   * This can be used recursively through compile_lambda(), which may reallocate
   * "def_functions".
   * Returns OK or FAIL.
   */
      int
! compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
  {
      char_u    *line = NULL;
      char_u    *p;
--- 7419,7434 ----
   * After ex_function() has collected all the function lines: parse and compile
   * the lines into instructions.
   * Adds the function to "def_functions".
!  * When "check_return_type" is set then set ufunc->uf_ret_type to the type of
!  * the return statement (used for lambda).  When uf_ret_type is already set
!  * then check that it matches.
   * "outer_cctx" is set for a nested function.
   * This can be used recursively through compile_lambda(), which may reallocate
   * "def_functions".
   * Returns OK or FAIL.
   */
      int
! compile_def_function(ufunc_T *ufunc, int check_return_type, cctx_T 
*outer_cctx)
  {
      char_u    *line = NULL;
      char_u    *p;
***************
*** 7797,7803 ****
                    goto erret;
  
            case CMD_return:
!                   line = compile_return(p, set_return_type, &cctx);
                    cctx.ctx_had_return = TRUE;
                    break;
  
--- 7800,7806 ----
                    goto erret;
  
            case CMD_return:
!                   line = compile_return(p, check_return_type, &cctx);
                    cctx.ctx_had_return = TRUE;
                    break;
  
*** ../vim-8.2.2208/src/userfunc.c      2020-12-24 16:05:54.339860228 +0100
--- src/userfunc.c      2020-12-25 12:09:31.763975556 +0100
***************
*** 349,355 ****
                    // will get the type from the default value
                    type = &t_unknown;
                else
!                   type = parse_type(&p, &fp->uf_type_list);
                if (type == NULL)
                    return FAIL;
                fp->uf_arg_types[i] = type;
--- 349,355 ----
                    // will get the type from the default value
                    type = &t_unknown;
                else
!                   type = parse_type(&p, &fp->uf_type_list, TRUE);
                if (type == NULL)
                    return FAIL;
                fp->uf_arg_types[i] = type;
***************
*** 369,375 ****
                // todo: get type from default value
                fp->uf_va_type = &t_any;
            else
!               fp->uf_va_type = parse_type(&p, &fp->uf_type_list);
            if (fp->uf_va_type == NULL)
                return FAIL;
        }
--- 369,375 ----
                // todo: get type from default value
                fp->uf_va_type = &t_any;
            else
!               fp->uf_va_type = parse_type(&p, &fp->uf_type_list, TRUE);
            if (fp->uf_va_type == NULL)
                return FAIL;
        }
***************
*** 460,476 ****
  
  /*
   * Skip over "->" or "=>" after the arguments of a lambda.
   * Return NULL if no valid arrow found.
   */
      static char_u *
! skip_arrow(char_u *start, int equal_arrow)
  {
      char_u *s = start;
  
      if (equal_arrow)
      {
        if (*s == ':')
!           s = skip_type(skipwhite(s + 1), TRUE);
        s = skipwhite(s);
        if (*s != '=')
            return NULL;
--- 460,481 ----
  
  /*
   * Skip over "->" or "=>" after the arguments of a lambda.
+  * If ": type" is found make "ret_type" point to "type".
   * Return NULL if no valid arrow found.
   */
      static char_u *
! skip_arrow(char_u *start, int equal_arrow, char_u **ret_type)
  {
      char_u *s = start;
  
      if (equal_arrow)
      {
        if (*s == ':')
!       {
!           s = skipwhite(s + 1);
!           *ret_type = s;
!           s = skip_type(s, TRUE);
!       }
        s = skipwhite(s);
        if (*s != '=')
            return NULL;
***************
*** 503,508 ****
--- 508,514 ----
      ufunc_T   *fp = NULL;
      partial_T   *pt = NULL;
      int               varargs;
+     char_u    *ret_type = NULL;
      int               ret;
      char_u    *s;
      char_u    *start, *end;
***************
*** 517,535 ****
      ga_init(&newargs);
      ga_init(&newlines);
  
!     // First, check if this is a lambda expression. "->" or "=>" must exist.
      s = skipwhite(*arg + 1);
      ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
            types_optional ? &argtypes : NULL, types_optional,
                                                 NULL, NULL, TRUE, NULL, NULL);
!     if (ret == FAIL || skip_arrow(s, equal_arrow) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
        return NOTDONE;
      }
  
!     // Parse the arguments again.
      if (evaluate)
        pnewargs = &newargs;
      else
--- 523,542 ----
      ga_init(&newargs);
      ga_init(&newlines);
  
!     // First, check if this is really a lambda expression. "->" or "=>" must
!     // be found after the arguments.
      s = skipwhite(*arg + 1);
      ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
            types_optional ? &argtypes : NULL, types_optional,
                                                 NULL, NULL, TRUE, NULL, NULL);
!     if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
        return NOTDONE;
      }
  
!     // Parse the arguments for real.
      if (evaluate)
        pnewargs = &newargs;
      else
***************
*** 538,544 ****
      ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs,
            types_optional ? &argtypes : NULL, types_optional,
                                            &varargs, NULL, FALSE, NULL, NULL);
!     if (ret == FAIL || (*arg = skip_arrow(*arg, equal_arrow)) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
--- 545,552 ----
      ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs,
            types_optional ? &argtypes : NULL, types_optional,
                                            &varargs, NULL, FALSE, NULL, NULL);
!     if (ret == FAIL
!                 || (*arg = skip_arrow(*arg, equal_arrow, &ret_type)) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
***************
*** 551,561 ****
  
      *arg = skipwhite_and_linebreak(*arg, evalarg);
  
!     // Only recognize "{" as the start of a function body when followed by
!     // white space, "{key: val}" is a dict.
!     if (equal_arrow && **arg == '{' && IS_WHITE_OR_NUL((*arg)[1]))
      {
        // TODO: process the function body upto the "}".
        emsg("Lambda function body not supported yet");
        goto errret;
      }
--- 559,569 ----
  
      *arg = skipwhite_and_linebreak(*arg, evalarg);
  
!     // Recognize "{" as the start of a function body.
!     if (equal_arrow && **arg == '{')
      {
        // TODO: process the function body upto the "}".
+       // Return type is required then.
        emsg("Lambda function body not supported yet");
        goto errret;
      }
***************
*** 619,627 ****
        hash_add(&func_hashtab, UF2HIKEY(fp));
        fp->uf_args = newargs;
        ga_init(&fp->uf_def_args);
!       if (types_optional
!                        && parse_argument_types(fp, &argtypes, FALSE) == FAIL)
!           goto errret;
  
        fp->uf_lines = newlines;
        if (current_funccal != NULL && eval_lavars)
--- 627,644 ----
        hash_add(&func_hashtab, UF2HIKEY(fp));
        fp->uf_args = newargs;
        ga_init(&fp->uf_def_args);
!       if (types_optional)
!       {
!           if (parse_argument_types(fp, &argtypes, FALSE) == FAIL)
!               goto errret;
!           if (ret_type != NULL)
!           {
!               fp->uf_ret_type = parse_type(&ret_type,
!                                                     &fp->uf_type_list, TRUE);
!               if (fp->uf_ret_type == NULL)
!                   goto errret;
!           }
!       }
  
        fp->uf_lines = newlines;
        if (current_funccal != NULL && eval_lavars)
***************
*** 3752,3758 ****
        else
        {
            p = ret_type;
!           fp->uf_ret_type = parse_type(&p, &fp->uf_type_list);
        }
        SOURCING_LNUM = lnum_save;
      }
--- 3769,3775 ----
        else
        {
            p = ret_type;
!           fp->uf_ret_type = parse_type(&p, &fp->uf_type_list, TRUE);
        }
        SOURCING_LNUM = lnum_save;
      }
*** ../vim-8.2.2208/src/vim9type.c      2020-11-16 20:08:32.395713947 +0100
--- src/vim9type.c      2020-12-25 12:09:26.867986864 +0100
***************
*** 596,623 ****
   * Returns NULL in case of failure.
   */
      static type_T *
! parse_type_member(char_u **arg, type_T *type, garray_T *type_gap)
  {
      type_T  *member_type;
      int           prev_called_emsg = called_emsg;
  
      if (**arg != '<')
      {
!       if (*skipwhite(*arg) == '<')
!           semsg(_(e_no_white_space_allowed_before_str), "<");
!       else
!           emsg(_(e_missing_type));
!       return type;
      }
      *arg = skipwhite(*arg + 1);
  
!     member_type = parse_type(arg, type_gap);
  
      *arg = skipwhite(*arg);
      if (**arg != '>' && called_emsg == prev_called_emsg)
      {
!       emsg(_(e_missing_gt_after_type));
!       return type;
      }
      ++*arg;
  
--- 596,633 ----
   * Returns NULL in case of failure.
   */
      static type_T *
! parse_type_member(
!       char_u      **arg,
!       type_T      *type,
!       garray_T    *type_gap,
!       int         give_error)
  {
      type_T  *member_type;
      int           prev_called_emsg = called_emsg;
  
      if (**arg != '<')
      {
!       if (give_error)
!       {
!           if (*skipwhite(*arg) == '<')
!               semsg(_(e_no_white_space_allowed_before_str), "<");
!           else
!               emsg(_(e_missing_type));
!       }
!       return NULL;
      }
      *arg = skipwhite(*arg + 1);
  
!     member_type = parse_type(arg, type_gap, give_error);
!     if (member_type == NULL)
!       return NULL;
  
      *arg = skipwhite(*arg);
      if (**arg != '>' && called_emsg == prev_called_emsg)
      {
!       if (give_error)
!           emsg(_(e_missing_gt_after_type));
!       return NULL;
      }
      ++*arg;
  
***************
*** 628,637 ****
  
  /*
   * Parse a type at "arg" and advance over it.
!  * Return &t_any for failure.
   */
      type_T *
! parse_type(char_u **arg, garray_T *type_gap)
  {
      char_u  *p = *arg;
      size_t  len;
--- 638,648 ----
  
  /*
   * Parse a type at "arg" and advance over it.
!  * When "give_error" is TRUE give error messages, otherwise be quiet.
!  * Return NULL for failure.
   */
      type_T *
! parse_type(char_u **arg, garray_T *type_gap, int give_error)
  {
      char_u  *p = *arg;
      size_t  len;
***************
*** 673,679 ****
            if (len == 4 && STRNCMP(*arg, "dict", len) == 0)
            {
                *arg += len;
!               return parse_type_member(arg, &t_dict_any, type_gap);
            }
            break;
        case 'f':
--- 684,691 ----
            if (len == 4 && STRNCMP(*arg, "dict", len) == 0)
            {
                *arg += len;
!               return parse_type_member(arg, &t_dict_any,
!                                                        type_gap, give_error);
            }
            break;
        case 'f':
***************
*** 683,690 ****
                *arg += len;
                return &t_float;
  #else
!               emsg(_(e_this_vim_is_not_compiled_with_float_support));
!               return &t_any;
  #endif
            }
            if (len == 4 && STRNCMP(*arg, "func", len) == 0)
--- 695,703 ----
                *arg += len;
                return &t_float;
  #else
!               if (give_error)
!                   emsg(_(e_this_vim_is_not_compiled_with_float_support));
!               return NULL;
  #endif
            }
            if (len == 4 && STRNCMP(*arg, "func", len) == 0)
***************
*** 721,731 ****
                        }
                        else if (first_optional != -1)
                        {
!                           
emsg(_(e_mandatory_argument_after_optional_argument));
!                           return &t_any;
                        }
  
!                       arg_type[argcount++] = parse_type(&p, type_gap);
  
                        // Nothing comes after "...{type}".
                        if (flags & TTFLAG_VARARGS)
--- 734,748 ----
                        }
                        else if (first_optional != -1)
                        {
!                           if (give_error)
!                               
emsg(_(e_mandatory_argument_after_optional_argument));
!                           return NULL;
                        }
  
!                       type = parse_type(&p, type_gap, give_error);
!                       if (type == NULL)
!                           return NULL;
!                       arg_type[argcount++] = type;
  
                        // Nothing comes after "...{type}".
                        if (flags & TTFLAG_VARARGS)
***************
*** 733,763 ****
  
                        if (*p != ',' && *skipwhite(p) == ',')
                        {
!                           semsg(_(e_no_white_space_allowed_before_str), ",");
!                           return &t_any;
                        }
                        if (*p == ',')
                        {
                            ++p;
                            if (!VIM_ISWHITE(*p))
                            {
!                               semsg(_(e_white_space_required_after_str), ",");
!                               return &t_any;
                            }
                        }
                        p = skipwhite(p);
                        if (argcount == MAX_FUNC_ARGS)
                        {
!                           emsg(_(e_too_many_argument_types));
!                           return &t_any;
                        }
                    }
  
                    p = skipwhite(p);
                    if (*p != ')')
                    {
!                       emsg(_(e_missing_close));
!                       return &t_any;
                    }
                    *arg = p + 1;
                }
--- 750,784 ----
  
                        if (*p != ',' && *skipwhite(p) == ',')
                        {
!                           if (give_error)
!                               semsg(_(e_no_white_space_allowed_before_str), 
",");
!                           return NULL;
                        }
                        if (*p == ',')
                        {
                            ++p;
                            if (!VIM_ISWHITE(*p))
                            {
!                               if (give_error)
!                                   semsg(_(e_white_space_required_after_str), 
",");
!                               return NULL;
                            }
                        }
                        p = skipwhite(p);
                        if (argcount == MAX_FUNC_ARGS)
                        {
!                           if (give_error)
!                               emsg(_(e_too_many_argument_types));
!                           return NULL;
                        }
                    }
  
                    p = skipwhite(p);
                    if (*p != ')')
                    {
!                       if (give_error)
!                           emsg(_(e_missing_close));
!                       return NULL;
                    }
                    *arg = p + 1;
                }
***************
*** 765,774 ****
                {
                    // parse return type
                    ++*arg;
!                   if (!VIM_ISWHITE(**arg))
                        semsg(_(e_white_space_required_after_str), ":");
                    *arg = skipwhite(*arg);
!                   ret_type = parse_type(arg, type_gap);
                }
                if (flags == 0 && first_optional == -1 && argcount <= 0)
                    type = get_func_type(ret_type, argcount, type_gap);
--- 786,797 ----
                {
                    // parse return type
                    ++*arg;
!                   if (!VIM_ISWHITE(**arg) && give_error)
                        semsg(_(e_white_space_required_after_str), ":");
                    *arg = skipwhite(*arg);
!                   ret_type = parse_type(arg, type_gap, give_error);
!                   if (ret_type == NULL)
!                       return NULL;
                }
                if (flags == 0 && first_optional == -1 && argcount <= 0)
                    type = get_func_type(ret_type, argcount, type_gap);
***************
*** 783,789 ****
                                                   ? argcount : first_optional;
                        if (func_type_add_arg_types(type, argcount,
                                                             type_gap) == FAIL)
!                           return &t_any;
                        mch_memmove(type->tt_args, arg_type,
                                                  sizeof(type_T *) * argcount);
                    }
--- 806,812 ----
                                                   ? argcount : first_optional;
                        if (func_type_add_arg_types(type, argcount,
                                                             type_gap) == FAIL)
!                           return NULL;
                        mch_memmove(type->tt_args, arg_type,
                                                  sizeof(type_T *) * argcount);
                    }
***************
*** 802,808 ****
            if (len == 4 && STRNCMP(*arg, "list", len) == 0)
            {
                *arg += len;
!               return parse_type_member(arg, &t_list_any, type_gap);
            }
            break;
        case 'n':
--- 825,832 ----
            if (len == 4 && STRNCMP(*arg, "list", len) == 0)
            {
                *arg += len;
!               return parse_type_member(arg, &t_list_any,
!                                                        type_gap, give_error);
            }
            break;
        case 'n':
***************
*** 828,835 ****
            break;
      }
  
!     semsg(_(e_type_not_recognized_str), *arg);
!     return &t_any;
  }
  
  /*
--- 852,860 ----
            break;
      }
  
!     if (give_error)
!       semsg(_(e_type_not_recognized_str), *arg);
!     return NULL;
  }
  
  /*
***************
*** 1016,1024 ****
      char *
  type_name(type_T *type, char **tofree)
  {
!     char *name = vartype_name(type->tt_type);
  
      *tofree = NULL;
      if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
      {
        char *member_free;
--- 1041,1052 ----
      char *
  type_name(type_T *type, char **tofree)
  {
!     char *name;
  
      *tofree = NULL;
+     if (type == NULL)
+       return "[unknown]";
+     name = vartype_name(type->tt_type);
      if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
      {
        char *member_free;
*** ../vim-8.2.2208/src/proto/vim9type.pro      2020-11-16 20:08:32.395713947 
+0100
--- src/proto/vim9type.pro      2020-12-25 12:04:20.552586070 +0100
***************
*** 17,23 ****
  int check_type(type_T *expected, type_T *actual, int give_msg, int argidx);
  int check_arg_type(type_T *expected, type_T *actual, int argidx);
  char_u *skip_type(char_u *start, int optional);
! type_T *parse_type(char_u **arg, garray_T *type_gap);
  void common_type(type_T *type1, type_T *type2, type_T **dest, garray_T 
*type_gap);
  type_T *get_member_type_from_stack(type_T **stack_top, int count, int skip, 
garray_T *type_gap);
  char *vartype_name(vartype_T type);
--- 17,23 ----
  int check_type(type_T *expected, type_T *actual, int give_msg, int argidx);
  int check_arg_type(type_T *expected, type_T *actual, int argidx);
  char_u *skip_type(char_u *start, int optional);
! type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error);
  void common_type(type_T *type1, type_T *type2, type_T **dest, garray_T 
*type_gap);
  type_T *get_member_type_from_stack(type_T **stack_top, int count, int skip, 
garray_T *type_gap);
  char *vartype_name(vartype_T type);
*** ../vim-8.2.2208/src/vim9script.c    2020-12-05 14:44:33.512669314 +0100
--- src/vim9script.c    2020-12-25 12:01:59.572766021 +0100
***************
*** 511,517 ****
      char_u        *name;
      scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
      type_T        *type;
-     int                   called_emsg_before = called_emsg;
      typval_T      init_tv;
  
      if (eap->cmdidx == CMD_final || eap->cmdidx == CMD_const)
--- 511,516 ----
***************
*** 548,555 ****
  
      // parse type
      p = skipwhite(p + 1);
!     type = parse_type(&p, &si->sn_type_list);
!     if (called_emsg != called_emsg_before)
      {
        vim_free(name);
        return p;
--- 547,554 ----
  
      // parse type
      p = skipwhite(p + 1);
!     type = parse_type(&p, &si->sn_type_list, TRUE);
!     if (type == NULL)
      {
        vim_free(name);
        return p;
*** ../vim-8.2.2208/src/eval.c  2020-12-24 17:15:49.909113037 +0100
--- src/eval.c  2020-12-25 11:53:57.617883182 +0100
***************
*** 868,874 ****
                char_u   *tp = skipwhite(p + 1);
  
                // parse the type after the name
!               lp->ll_type = parse_type(&tp, &si->sn_type_list);
                lp->ll_name_end = tp;
            }
        }
--- 868,876 ----
                char_u   *tp = skipwhite(p + 1);
  
                // parse the type after the name
!               lp->ll_type = parse_type(&tp, &si->sn_type_list, !quiet);
!               if (lp->ll_type == NULL && !quiet)
!                   return NULL;
                lp->ll_name_end = tp;
            }
        }
*** ../vim-8.2.2208/src/testdir/test_vim9_expr.vim      2020-12-24 
15:13:35.850860411 +0100
--- src/testdir/test_vim9_expr.vim      2020-12-25 12:34:12.367693002 +0100
***************
*** 1951,1957 ****
        assert_equal([1, 3, 5], res)
  
        # Lambda returning a dict
!       var Lmb = () => {key: 42}
        assert_equal({key: 42}, Lmb())
    END
    CheckDefSuccess(lines)
--- 1951,1957 ----
        assert_equal([1, 3, 5], res)
  
        # Lambda returning a dict
!       var Lmb = () => ({key: 42})
        assert_equal({key: 42}, Lmb())
    END
    CheckDefSuccess(lines)
***************
*** 1960,1970 ****
    CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1001:')
    CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1001:')
  
    CheckDefFailure(["filter([1, 2], (k,v) => 1)"], 'E1069:', 1)
    # error is in first line of the lambda
    CheckDefFailure(["var L = (a) -> a + b"], 'E1001:', 1)
  
! # TODO: lambda after -> doesn't work yet
  #  assert_equal('xxxyyy', 'xxx'->((a, b) => a .. b)('yyy'))
  
  #  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
--- 1960,1975 ----
    CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1001:')
    CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1001:')
  
+   CheckDefSuccess(["var Ref: func(number): string = (a: number): string => 
'x'"])
+   CheckDefSuccess(["var Ref: func(number): any = (a: number): any => 'x'"])
+   CheckDefFailure(["var Ref: func(number): number = (a: number): string => 
'x'"], 'E1012:')
+   CheckDefFailure(["var Ref: func(number): string = (a: number): string => 
99"], 'E1012:')
+ 
    CheckDefFailure(["filter([1, 2], (k,v) => 1)"], 'E1069:', 1)
    # error is in first line of the lambda
    CheckDefFailure(["var L = (a) -> a + b"], 'E1001:', 1)
  
! # TODO: ->(lambda)() doesn't work yet
  #  assert_equal('xxxyyy', 'xxx'->((a, b) => a .. b)('yyy'))
  
  #  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
***************
*** 1973,1981 ****
  #        'E1106: 2 arguments too many')
  #  CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)
  
!   CheckDefSuccess(['var Fx = (a) => {k1: 0,', ' k2: 1}'])
!   CheckDefFailure(['var Fx = (a) => {k1: 0', ' k2: 1}'], 'E722:', 2)
!   CheckDefFailure(['var Fx = (a) => {k1: 0,', ' k2 1}'], 'E720:', 2)
  
    CheckDefSuccess(['var Fx = (a) => [0,', ' 1]'])
    CheckDefFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
--- 1978,1986 ----
  #        'E1106: 2 arguments too many')
  #  CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)
  
!   CheckDefSuccess(['var Fx = (a) => ({k1: 0,', ' k2: 1})'])
!   CheckDefFailure(['var Fx = (a) => ({k1: 0', ' k2: 1})'], 'E722:', 2)
!   CheckDefFailure(['var Fx = (a) => ({k1: 0,', ' k2 1})'], 'E720:', 2)
  
    CheckDefSuccess(['var Fx = (a) => [0,', ' 1]'])
    CheckDefFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
*** ../vim-8.2.2208/src/version.c       2020-12-24 21:56:37.647479568 +0100
--- src/version.c       2020-12-25 12:37:04.083228394 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2209,
  /**/

-- 
"Making it up?  Why should I want to make anything up?  Life's bad enough
as it is without wanting to invent any more of it."
                -- Marvin, the Paranoid Android in Douglas Adams'
                   "The Hitchhiker's Guide to the Galaxy"

 /// 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/202012251138.0BPBclAS3476667%40masaka.moolenaar.net.

Raspunde prin e-mail lui