Patch 8.2.2257
Problem:    Vim9: using -> for lambda is ambiguous.
Solution:   Stop supporting ->, must use =>.
Files:      src/eval.c, src/vim9compile.c, src/testdir/test_vim9_assign.vim,
            src/testdir/test_vim9_builtin.vim, src/testdir/test_vim9_cmd.vim,
            src/testdir/test_vim9_disassemble.vim,
            src/testdir/test_vim9_expr.vim, src/testdir/test_vim9_func.vim,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.2256/src/eval.c  2020-12-30 21:16:27.727686851 +0100
--- src/eval.c  2020-12-31 21:18:44.197465563 +0100
***************
*** 3316,3322 ****
       * Lambda: {arg, arg -> expr}
       * Dictionary: {'key': val, 'key': val}
       */
!     case '{': ret = get_lambda_tv(arg, rettv, in_vim9script(), evalarg);
                if (ret == NOTDONE)
                    ret = eval_dict(arg, rettv, evalarg, FALSE);
                break;
--- 3316,3325 ----
       * Lambda: {arg, arg -> expr}
       * Dictionary: {'key': val, 'key': val}
       */
!     case '{': if (in_vim9script())
!                   ret = NOTDONE;
!               else
!                   ret = get_lambda_tv(arg, rettv, in_vim9script(), evalarg);
                if (ret == NOTDONE)
                    ret = eval_dict(arg, rettv, evalarg, FALSE);
                break;
***************
*** 3617,3623 ****
      *arg += 2;
      rettv->v_type = VAR_UNKNOWN;
  
!     ret = get_lambda_tv(arg, rettv, FALSE, evalarg);
      if (ret != OK)
        return FAIL;
      else if (**arg != '(')
--- 3620,3643 ----
      *arg += 2;
      rettv->v_type = VAR_UNKNOWN;
  
!     if (**arg == '{')
!     {
!       // ->{lambda}()
!       ret = get_lambda_tv(arg, rettv, FALSE, evalarg);
!     }
!     else
!     {
!       // ->(lambda)()
!       ++*arg;
!       ret = eval1(arg, rettv, evalarg);
!       *arg = skipwhite_and_linebreak(*arg, evalarg);
!       if (**arg != ')')
!       {
!           emsg(_(e_missing_close));
!           ret = FAIL;
!       }
!       ++*arg;
!     }
      if (ret != OK)
        return FAIL;
      else if (**arg != '(')
***************
*** 5645,5652 ****
            *arg = p;
            if (ret == OK)
            {
!               if ((*arg)[2] == '{')
!                   // expr->{lambda}()
                    ret = eval_lambda(arg, rettv, evalarg, verbose);
                else
                    // expr->name()
--- 5665,5672 ----
            *arg = p;
            if (ret == OK)
            {
!               if (((*arg)[2] == '{' && !in_vim9script()) || (*arg)[2] == '(')
!                   // expr->{lambda}() or expr->(lambda)()
                    ret = eval_lambda(arg, rettv, evalarg, verbose);
                else
                    // expr->name()
*** ../vim-8.2.2256/src/vim9compile.c   2020-12-31 17:40:57.536087870 +0100
--- src/vim9compile.c   2020-12-31 19:52:38.426638262 +0100
***************
*** 2938,2944 ****
  }
  
  /*
!  * parse a lambda: "{arg, arg -> expr}" or "(arg, arg) => expr"
   * "*arg" points to the '{'.
   * Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
   */
--- 2938,2944 ----
  }
  
  /*
!  * Parse a lambda: "(arg, arg) => expr"
   * "*arg" points to the '{'.
   * Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
   */
***************
*** 2988,3039 ****
  }
  
  /*
-  * Compile a lamda call: expr->{lambda}(args)
-  * "arg" points to the "{".
-  */
-     static int
- compile_lambda_call(char_u **arg, cctx_T *cctx)
- {
-     ufunc_T   *ufunc;
-     typval_T  rettv;
-     int               argcount = 1;
-     int               ret = FAIL;
- 
-     // Get the funcref in "rettv".
-     if (get_lambda_tv(arg, &rettv, TRUE, &EVALARG_EVALUATE) == FAIL)
-       return FAIL;
- 
-     if (**arg != '(')
-     {
-       if (*skipwhite(*arg) == '(')
-           emsg(_(e_nowhitespace));
-       else
-           semsg(_(e_missing_paren), "lambda");
-       clear_tv(&rettv);
-       return FAIL;
-     }
- 
-     ufunc = rettv.vval.v_partial->pt_func;
-     ++ufunc->uf_refcount;
-     clear_tv(&rettv);
-     ga_init2(&ufunc->uf_type_list, sizeof(type_T *), 10);
- 
-     // The function will have one line: "return {expr}".  Compile it into
-     // instructions so that we get any errors right now.
-     compile_def_function(ufunc, TRUE, cctx);
- 
-     // compile the arguments
-     *arg = skipwhite(*arg + 1);
-     if (compile_arguments(arg, cctx, &argcount) == OK)
-       // call the compiled function
-       ret = generate_CALL(cctx, ufunc, argcount);
- 
-     if (ret == FAIL)
-       func_ptr_unref(ufunc);
-     return ret;
- }
- 
- /*
   * parse a dict: {key: val, [key]: val}
   * "*arg" points to the '{'.
   * ppconst->pp_is_const is set if all item values are a constant.
--- 2988,2993 ----
***************
*** 3602,3615 ****
            p += 2;
            *arg = skipwhite(p);
            // No line break supported right after "->".
!           if (**arg == '{')
!           {
!               // lambda call:  list->{lambda}
!               // TODO: remove this
!               if (compile_lambda_call(arg, cctx) == FAIL)
!                   return FAIL;
!           }
!           else if (**arg == '(')
            {
                int         argcount = 1;
                char_u      *expr;
--- 3556,3562 ----
            p += 2;
            *arg = skipwhite(p);
            // No line break supported right after "->".
!           if (**arg == '(')
            {
                int         argcount = 1;
                char_u      *expr;
***************
*** 3631,3637 ****
                ++*arg;
                if (**arg != '(')
                {
!                   semsg(_(e_missing_paren), *arg);
                    return FAIL;
                }
  
--- 3578,3587 ----
                ++*arg;
                if (**arg != '(')
                {
!                   if (*skipwhite(*arg) == '(')
!                       emsg(_(e_nowhitespace));
!                   else
!                       semsg(_(e_missing_paren), *arg);
                    return FAIL;
                }
  
***************
*** 4005,4020 ****
                    break;
  
        /*
-        * Lambda: {arg, arg -> expr}
         * Dictionary: {'key': val, 'key': val}
         */
!       case '{':   // Try parsing as a lambda, if NOTDONE is returned it
!                   // must be a dict.
!                   // TODO: if we go with the "(arg) => expr" syntax remove
!                   // this
!                   ret = compile_lambda(arg, cctx);
!                   if (ret == NOTDONE)
!                       ret = compile_dict(arg, cctx, ppconst);
                    break;
  
        /*
--- 3955,3963 ----
                    break;
  
        /*
         * Dictionary: {'key': val, 'key': val}
         */
!       case '{':   ret = compile_dict(arg, cctx, ppconst);
                    break;
  
        /*
*** ../vim-8.2.2256/src/testdir/test_vim9_assign.vim    2020-12-31 
17:40:57.536087870 +0100
--- src/testdir/test_vim9_assign.vim    2020-12-31 21:10:21.731523671 +0100
***************
*** 66,72 ****
    CheckDefFailure(['var x:string'], 'E1069:')
    CheckDefFailure(['var x:string = "x"'], 'E1069:')
    CheckDefFailure(['var a:string = "x"'], 'E1069:')
!   CheckDefFailure(['var lambda = {-> "lambda"}'], 'E704:')
    CheckScriptFailure(['var x = "x"'], 'E1124:')
  
    var nr: number = 1234
--- 66,72 ----
    CheckDefFailure(['var x:string'], 'E1069:')
    CheckDefFailure(['var x:string = "x"'], 'E1069:')
    CheckDefFailure(['var a:string = "x"'], 'E1069:')
!   CheckDefFailure(['var lambda = () => "lambda"'], 'E704:')
    CheckScriptFailure(['var x = "x"'], 'E1124:')
  
    var nr: number = 1234
***************
*** 1032,1042 ****
    # check if assign a lambda to a variable which type is func or any.
    var lines =<< trim END
        vim9script
!       var FuncRef = {-> 123}
        assert_equal(123, FuncRef())
!       var FuncRef_Func: func = {-> 123}
        assert_equal(123, FuncRef_Func())
!       var FuncRef_Any: any = {-> 123}
        assert_equal(123, FuncRef_Any())
    END
    CheckScriptSuccess(lines)
--- 1032,1042 ----
    # check if assign a lambda to a variable which type is func or any.
    var lines =<< trim END
        vim9script
!       var FuncRef = () => 123
        assert_equal(123, FuncRef())
!       var FuncRef_Func: func = () => 123
        assert_equal(123, FuncRef_Func())
!       var FuncRef_Any: any = () => 123
        assert_equal(123, FuncRef_Any())
    END
    CheckScriptSuccess(lines)
*** ../vim-8.2.2256/src/testdir/test_vim9_builtin.vim   2020-12-29 
20:25:16.470694750 +0100
--- src/testdir/test_vim9_builtin.vim   2020-12-31 19:14:38.022330888 +0100
***************
*** 231,237 ****
    assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, s:string_keep))
  
    var res: list<dict<any>>
!   extend(res, map([1, 2], {_, v -> {}}))
    assert_equal([{}, {}], res)
  
    CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, 
expected list<number> but got number')
--- 231,237 ----
    assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, s:string_keep))
  
    var res: list<dict<any>>
!   extend(res, map([1, 2], (_, v) => ({})))
    assert_equal([{}, {}], res)
  
    CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, 
expected list<number> but got number')
***************
*** 254,260 ****
  
  
  def Wrong_dict_key_type(items: list<number>): list<number>
!   return filter(items, {_, val -> get({[val]: 1}, 'x')})
  enddef
  
  def Test_map_function_arg()
--- 254,260 ----
  
  
  def Wrong_dict_key_type(items: list<number>): list<number>
!   return filter(items, (_, val) => get({[val]: 1}, 'x'))
  enddef
  
  def Test_map_function_arg()
***************
*** 313,319 ****
  enddef
  
  def Test_filter_return_type()
!   var l = filter([1, 2, 3], {-> 1})
    var res = 0
    for n in l
      res += n
--- 313,319 ----
  enddef
  
  def Test_filter_return_type()
!   var l = filter([1, 2, 3], () => 1)
    var res = 0
    for n in l
      res += n
***************
*** 323,329 ****
  
  def Test_filter_missing_argument()
    var dict = {aa: [1], ab: [2], ac: [3], de: [4]}
!   var res = dict->filter({k -> k =~ 'a' && k !~ 'b'})
    res->assert_equal({aa: [1], ac: [3]})
  enddef
  
--- 323,329 ----
  
  def Test_filter_missing_argument()
    var dict = {aa: [1], ab: [2], ac: [3], de: [4]}
!   var res = dict->filter((k) => k =~ 'a' && k !~ 'b')
    res->assert_equal({aa: [1], ac: [3]})
  enddef
  
***************
*** 539,546 ****
  enddef
  
  def Test_readdir()
!    eval expand('sautest')->readdir({e -> e[0] !=# '.'})
!    eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
  enddef
  
  def Test_remove_return_type()
--- 539,546 ----
  enddef
  
  def Test_readdir()
!    eval expand('sautest')->readdir((e) => e[0] !=# '.')
!    eval expand('sautest')->readdirex((e) => e.name[0] !=# '.')
  enddef
  
  def Test_remove_return_type()
***************
*** 566,581 ****
    setline(1, ['foo', 'bar'])
    var val = 0
    # skip expr returns boolean
!   search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
    :1
!   search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
    # skip expr returns number, only 0 and 1 are accepted
    :1
!   search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
    :1
!   search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
!   assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
!   assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
  enddef
  
  def Test_searchcount()
--- 566,581 ----
    setline(1, ['foo', 'bar'])
    var val = 0
    # skip expr returns boolean
!   search('bar', 'W', 0, 0, () => val == 1)->assert_equal(2)
    :1
!   search('bar', 'W', 0, 0, () => val == 0)->assert_equal(0)
    # skip expr returns number, only 0 and 1 are accepted
    :1
!   search('bar', 'W', 0, 0, () => 0)->assert_equal(2)
    :1
!   search('bar', 'W', 0, 0, () => 1)->assert_equal(0)
!   assert_fails("search('bar', '', 0, 0, () => -1)", 'E1023:')
!   assert_fails("search('bar', '', 0, 0, () => -1)", 'E1023:')
  enddef
  
  def Test_searchcount()
***************
*** 667,673 ****
  
  def Test_submatch()
    var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
!   var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
    var actual = substitute('A123456789', pat, Rep, '')
    var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], 
['7'], ['8'], ['9']]"
    actual->assert_equal(expected)
--- 667,673 ----
  
  def Test_submatch()
    var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
!   var Rep = () => range(10)->map((_, v) => submatch(v, true))->string()
    var actual = substitute('A123456789', pat, Rep, '')
    var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], 
['7'], ['8'], ['9']]"
    actual->assert_equal(expected)
***************
*** 703,709 ****
  enddef
  
  def Test_timer_paused()
!   var id = timer_start(50, {-> 0})
    timer_pause(id, true)
    var info = timer_info(id)
    info[0]['paused']->assert_equal(1)
--- 703,709 ----
  enddef
  
  def Test_timer_paused()
!   var id = timer_start(50, () => 0)
    timer_pause(id, true)
    var info = timer_info(id)
    info[0]['paused']->assert_equal(1)
*** ../vim-8.2.2256/src/testdir/test_vim9_cmd.vim       2020-12-31 
17:40:57.536087870 +0100
--- src/testdir/test_vim9_cmd.vim       2020-12-31 21:11:31.523220547 +0100
***************
*** 305,311 ****
  def Test_skipped_expr_linebreak()
    if 0
      var x = []
!                ->map({ -> 0})
    endif
  enddef
  
--- 305,311 ----
  def Test_skipped_expr_linebreak()
    if 0
      var x = []
!                ->map(() => 0)
    endif
  enddef
  
***************
*** 368,374 ****
  
  def Test_filter_is_not_modifier()
    var tags = [{a: 1, b: 2}, {x: 3, y: 4}]
!   filter(tags, { _, v -> has_key(v, 'x') ? 1 : 0 })
    assert_equal([{x: 3, y: 4}], tags)
  enddef
  
--- 368,374 ----
  
  def Test_filter_is_not_modifier()
    var tags = [{a: 1, b: 2}, {x: 3, y: 4}]
!   filter(tags, ( _, v) => has_key(v, 'x') ? 1 : 0 )
    assert_equal([{x: 3, y: 4}], tags)
  enddef
  
*** ../vim-8.2.2256/src/testdir/test_vim9_disassemble.vim       2020-12-30 
20:39:17.454007601 +0100
--- src/testdir/test_vim9_disassemble.vim       2020-12-31 20:34:12.503267306 
+0100
***************
*** 896,902 ****
  enddef
  
  def WithLambda(): string
!   var F = {a -> "X" .. a .. "X"}
    return F("x")
  enddef
  
--- 896,902 ----
  enddef
  
  def WithLambda(): string
!   var F = (a) => "X" .. a .. "X"
    return F("x")
  enddef
  
***************
*** 904,910 ****
    assert_equal("XxX", WithLambda())
    var instr = execute('disassemble WithLambda')
    assert_match('WithLambda\_s*' ..
!         'var F = {a -> "X" .. a .. "X"}\_s*' ..
          '\d FUNCREF <lambda>\d\+\_s*' ..
          '\d STORE $0\_s*' ..
          'return F("x")\_s*' ..
--- 904,910 ----
    assert_equal("XxX", WithLambda())
    var instr = execute('disassemble WithLambda')
    assert_match('WithLambda\_s*' ..
!         'var F = (a) => "X" .. a .. "X"\_s*' ..
          '\d FUNCREF <lambda>\d\+\_s*' ..
          '\d STORE $0\_s*' ..
          'return F("x")\_s*' ..
***************
*** 929,935 ****
  enddef
  
  def LambdaWithType(): number
!   var Ref = {a: number -> a + 10}
    return Ref(g:value)
  enddef
  
--- 929,935 ----
  enddef
  
  def LambdaWithType(): number
!   var Ref = (a: number) => a + 10
    return Ref(g:value)
  enddef
  
***************
*** 938,944 ****
    assert_equal(15, LambdaWithType())
    var instr = execute('disassemble LambdaWithType')
    assert_match('LambdaWithType\_s*' ..
!         'var Ref = {a: number -> a + 10}\_s*' ..
          '\d FUNCREF <lambda>\d\+\_s*' ..
          '\d STORE $0\_s*' ..
          'return Ref(g:value)\_s*' ..
--- 938,944 ----
    assert_equal(15, LambdaWithType())
    var instr = execute('disassemble LambdaWithType')
    assert_match('LambdaWithType\_s*' ..
!         'var Ref = (a: number) => a + 10\_s*' ..
          '\d FUNCREF <lambda>\d\+\_s*' ..
          '\d STORE $0\_s*' ..
          'return Ref(g:value)\_s*' ..
***************
*** 1541,1550 ****
          ['{a: 1} is aDict', 'COMPAREDICT is'],
          ['{a: 1} isnot aDict', 'COMPAREDICT isnot'],
  
!         ['{-> 33} == {-> 44}', 'COMPAREFUNC =='],
!         ['{-> 33} != {-> 44}', 'COMPAREFUNC !='],
!         ['{-> 33} is {-> 44}', 'COMPAREFUNC is'],
!         ['{-> 33} isnot {-> 44}', 'COMPAREFUNC isnot'],
  
          ['77 == g:xx', 'COMPAREANY =='],
          ['77 != g:xx', 'COMPAREANY !='],
--- 1541,1550 ----
          ['{a: 1} is aDict', 'COMPAREDICT is'],
          ['{a: 1} isnot aDict', 'COMPAREDICT isnot'],
  
!         ['(() => 33) == (() => 44)', 'COMPAREFUNC =='],
!         ['(() => 33) != (() => 44)', 'COMPAREFUNC !='],
!         ['(() => 33) is (() => 44)', 'COMPAREFUNC is'],
!         ['(() => 33) isnot (() => 44)', 'COMPAREFUNC isnot'],
  
          ['77 == g:xx', 'COMPAREANY =='],
          ['77 != g:xx', 'COMPAREANY !='],
*** ../vim-8.2.2256/src/testdir/test_vim9_expr.vim      2020-12-31 
13:31:20.521507996 +0100
--- src/testdir/test_vim9_expr.vim      2020-12-31 21:14:13.210543297 +0100
***************
*** 1806,1863 ****
  enddef
  
  def LambdaWithComments(): func
!   return {x ->
              # some comment
              x == 1
              # some comment
              ||
              x == 2
-         }
  enddef
  
  def LambdaUsingArg(x: number): func
!   return {->
              # some comment
              x == 1
              # some comment
              ||
              x == 2
-         }
  enddef
  
  def Test_expr7_lambda()
    var lines =<< trim END
!       var La = { -> 'result'}
        assert_equal('result', La())
!       assert_equal([1, 3, 5], [1, 2, 3]->map({key, val -> key + val}))
  
        # line continuation inside lambda with "cond ? expr : expr" works
        var ll = range(3)
!       map(ll, {k, v -> v % 2 ? {
                  ['111']: 111 } : {}
!             })
        assert_equal([{}, {111: 111}, {}], ll)
  
        ll = range(3)
!       map(ll, {k, v -> v == 8 || v
                      == 9
                      || v % 2 ? 111 : 222
!             })
        assert_equal([222, 111, 222], ll)
  
        ll = range(3)
!       map(ll, {k, v -> v != 8 && v
                      != 9
                      && v % 2 == 0 ? 111 : 222
!             })
        assert_equal([111, 222, 111], ll)
  
!       var dl = [{key: 0}, {key: 22}]->filter({ _, v -> v['key'] })
        assert_equal([{key: 22}], dl)
  
        dl = [{key: 12}, {['foo']: 34}]
        assert_equal([{key: 12}], filter(dl,
!             {_, v -> has_key(v, 'key') ? v['key'] == 12 : 0}))
  
        assert_equal(false, LambdaWithComments()(0))
        assert_equal(true, LambdaWithComments()(1))
--- 1806,1861 ----
  enddef
  
  def LambdaWithComments(): func
!   return (x) =>
              # some comment
              x == 1
              # some comment
              ||
              x == 2
  enddef
  
  def LambdaUsingArg(x: number): func
!   return () =>
              # some comment
              x == 1
              # some comment
              ||
              x == 2
  enddef
  
  def Test_expr7_lambda()
    var lines =<< trim END
!       var La = () => 'result'
        assert_equal('result', La())
!       assert_equal([1, 3, 5], [1, 2, 3]->map((key, val) => key + val))
  
        # line continuation inside lambda with "cond ? expr : expr" works
        var ll = range(3)
!       map(ll, (k, v) => v % 2 ? {
                  ['111']: 111 } : {}
!             )
        assert_equal([{}, {111: 111}, {}], ll)
  
        ll = range(3)
!       map(ll, (k, v) => v == 8 || v
                      == 9
                      || v % 2 ? 111 : 222
!             )
        assert_equal([222, 111, 222], ll)
  
        ll = range(3)
!       map(ll, (k, v) => v != 8 && v
                      != 9
                      && v % 2 == 0 ? 111 : 222
!             )
        assert_equal([111, 222, 111], ll)
  
!       var dl = [{key: 0}, {key: 22}]->filter(( _, v) => v['key'] )
        assert_equal([{key: 22}], dl)
  
        dl = [{key: 12}, {['foo']: 34}]
        assert_equal([{key: 12}], filter(dl,
!             (_, v) => has_key(v, 'key') ? v['key'] == 12 : 0))
  
        assert_equal(false, LambdaWithComments()(0))
        assert_equal(true, LambdaWithComments()(1))
***************
*** 1867,1899 ****
        assert_equal(false, LambdaUsingArg(0)())
        assert_equal(true, LambdaUsingArg(1)())
  
!       var res = map([1, 2, 3], {i: number, v: number -> i + v})
        assert_equal([1, 3, 5], res)
    END
    CheckDefAndScriptSuccess(lines)
  
!   CheckDefFailure(["var Ref = {a->a + 1}"], 'E1004:')
!   CheckDefFailure(["var Ref = {a-> a + 1}"], 'E1004:')
!   CheckDefFailure(["var Ref = {a ->a + 1}"], 'E1004:')
  
!   CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
    # error is in first line of the lambda
!   CheckDefFailure(["var L = {a -> a + b}"], 'E1001:', 0)
  
!   assert_equal('xxxyyy', 'xxx'->{a, b -> a .. b}('yyy'))
  
!   CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
!         'E1106: One argument too many')
!   CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x', 'y')"],
!         '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)
  enddef
  
  def NewLambdaWithComments(): func
--- 1865,1895 ----
        assert_equal(false, LambdaUsingArg(0)())
        assert_equal(true, LambdaUsingArg(1)())
  
!       var res = map([1, 2, 3], (i: number, v: number) => i + v)
        assert_equal([1, 3, 5], res)
    END
    CheckDefAndScriptSuccess(lines)
  
!   CheckDefFailure(["var Ref = (a)=>a + 1"], 'E1004:')
!   CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1004:')
!   CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1004:')
  
!   CheckDefFailure(["filter([1, 2], (k,v) => 1)"], 'E1069:', 1)
    # error is in first line of the lambda
!   CheckDefFailure(["var L = (a) => a + b"], 'E1001:', 0)
! 
!   assert_equal('xxxyyy', 'xxx'->((a, b) => a .. b)('yyy'))
  
!   CheckDefExecFailure(["var s = 'asdf'->((a) => a)('x')"], 'E118:')
!   CheckDefExecFailure(["var s = 'asdf'->((a) => a)('x', 'y')"], 'E118:')
!   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)
  enddef
  
  def NewLambdaWithComments(): func
***************
*** 2002,2011 ****
  def Test_expr7_lambda_vim9script()
    var lines =<< trim END
        vim9script
!       var v = 10->{a ->
            a
              + 2
!         }()
        assert_equal(12, v)
    END
    CheckScriptSuccess(lines)
--- 1998,2007 ----
  def Test_expr7_lambda_vim9script()
    var lines =<< trim END
        vim9script
!       var v = 10->((a) =>
            a
              + 2
!             )()
        assert_equal(12, v)
    END
    CheckScriptSuccess(lines)
***************
*** 2013,2021 ****
    # nested lambda with line breaks
    lines =<< trim END
        vim9script
!       search('"', 'cW', 0, 0, {->
        synstack('.', col('.'))
!       ->map({_, v -> synIDattr(v, 'name')})->len()})
    END
    CheckScriptSuccess(lines)
  enddef
--- 2009,2017 ----
    # nested lambda with line breaks
    lines =<< trim END
        vim9script
!       search('"', 'cW', 0, 0, () =>
        synstack('.', col('.'))
!           ->map((_, v) => synIDattr(v, 'name'))->len())
    END
    CheckScriptSuccess(lines)
  enddef
***************
*** 2089,2096 ****
    CheckDefFailure(["var x = 'a' .. #{a: 1}"], 'E1097:', 3)
  
    CheckDefFailure(["var x = {a:8}"], 'E1069:', 1)
!   CheckDefFailure(["var x = {a : 8}"], 'E1059:', 1)
!   CheckDefFailure(["var x = {a :8}"], 'E1059:', 1)
    CheckDefFailure(["var x = {a: 8 , b: 9}"], 'E1068:', 1)
    CheckDefFailure(["var x = {a: 1,b: 2}"], 'E1069:', 1)
  
--- 2085,2092 ----
    CheckDefFailure(["var x = 'a' .. #{a: 1}"], 'E1097:', 3)
  
    CheckDefFailure(["var x = {a:8}"], 'E1069:', 1)
!   CheckDefFailure(["var x = {a : 8}"], 'E1068:', 1)
!   CheckDefFailure(["var x = {a :8}"], 'E1068:', 1)
    CheckDefFailure(["var x = {a: 8 , b: 9}"], 'E1068:', 1)
    CheckDefFailure(["var x = {a: 1,b: 2}"], 'E1069:', 1)
  
***************
*** 2139,2144 ****
--- 2135,2143 ----
                ['two']: 2,
                   }
        assert_equal({one: 1, two: 2}, d)
+ 
+       var dd = {k: 123->len()}
+       assert_equal(3, dd.k)
    END
    CheckScriptSuccess(lines)
  
***************
*** 2174,2180 ****
        vim9script
        var d = {one : 1}
    END
!   CheckScriptFailure(lines, 'E1059:', 2)
  
    lines =<< trim END
        vim9script
--- 2173,2179 ----
        vim9script
        var d = {one : 1}
    END
!   CheckScriptFailure(lines, 'E1068:', 2)
  
    lines =<< trim END
        vim9script
***************
*** 2629,2635 ****
        unlet g:false
  
        assert_equal(true, !test_null_partial())
!       assert_equal(false, !{-> 'yes'})
  
        assert_equal(true, !test_null_dict())
        assert_equal(true, !{})
--- 2628,2634 ----
        unlet g:false
  
        assert_equal(true, !test_null_partial())
!       assert_equal(false, !() => 'yes')
  
        assert_equal(true, !test_null_dict())
        assert_equal(true, !{})
***************
*** 2668,2675 ****
    call CheckDefFailure(["var x = [1, 2"], "E697:", 2)
    call CheckDefFailure(["var x = [notfound]"], "E1001:", 1)
  
!   call CheckDefFailure(["var x = { -> 123) }"], "E451:", 1)
!   call CheckDefFailure(["var x = 123->{x -> x + 5) }"], "E451:", 1)
  
    call CheckDefFailure(["var x = &notexist"], 'E113:', 1)
    call CheckDefFailure(["&grepprg = [343]"], 'E1012:', 1)
--- 2667,2674 ----
    call CheckDefFailure(["var x = [1, 2"], "E697:", 2)
    call CheckDefFailure(["var x = [notfound]"], "E1001:", 1)
  
!   call CheckDefFailure(["var X = () => 123)"], "E488:", 1)
!   call CheckDefFailure(["var x = 123->((x) => x + 5)"], "E107:", 1)
  
    call CheckDefFailure(["var x = &notexist"], 'E113:', 1)
    call CheckDefFailure(["&grepprg = [343]"], 'E1012:', 1)
***************
*** 2691,2697 ****
    call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: 
->', 1)
  
    call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
!   call CheckDefExecFailure(["{a: 1->len()"], 'E1004:', 1)
    call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
  endfunc
  
--- 2690,2696 ----
    call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: 
->', 1)
  
    call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
!   call CheckDefExecFailure(["{a: 1->len()"], 'E723:', 2)
    call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
  endfunc
  
***************
*** 2725,2736 ****
  
    # method call
    l = [2, 5, 6]
!   l->map({k, v -> k + v})
    assert_equal([2, 6, 8], l)
  
    # lambda method call
    l = [2, 5]
!   l->{l -> add(l, 8)}()
    assert_equal([2, 5, 8], l)
  
    # dict member
--- 2724,2735 ----
  
    # method call
    l = [2, 5, 6]
!   l->map((k, v) => k + v)
    assert_equal([2, 6, 8], l)
  
    # lambda method call
    l = [2, 5]
!   l->((l) => add(l, 8))()
    assert_equal([2, 5, 8], l)
  
    # dict member
***************
*** 2895,2902 ****
  enddef
  
  func Test_expr7_trailing_fails()
!   call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)}'], 'E107:', 2)
!   call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)} ()'], 'E274:', 2)
  endfunc
  
  func Test_expr_fails()
--- 2894,2901 ----
  enddef
  
  func Test_expr7_trailing_fails()
!   call CheckDefFailure(['var l = [2]', 'l->((l) => add(l, 8))'], 'E107:', 2)
!   call CheckDefFailure(['var l = [2]', 'l->((l) => add(l, 8)) ()'], 'E274:', 
2)
  endfunc
  
  func Test_expr_fails()
*** ../vim-8.2.2256/src/testdir/test_vim9_func.vim      2020-12-31 
18:28:13.706927452 +0100
--- src/testdir/test_vim9_func.vim      2020-12-31 20:28:50.536278664 +0100
***************
*** 54,60 ****
  enddef
  
  def CallMapRecursive(l: list<number>): number
!   return map(l, {_, v -> CallMapRecursive([v])})[0]
  enddef
  
  def Test_funcdepth_error()
--- 54,60 ----
  enddef
  
  def CallMapRecursive(l: list<number>): number
!   return map(l, (_, v) => CallMapRecursive([v]))[0]
  enddef
  
  def Test_funcdepth_error()
***************
*** 310,316 ****
        vim9script
        def Outer()
          def g:Inner()
!           echo map([1, 2, 3], {_, v -> v + 1})
          enddef
          g:Inner()
        enddef
--- 310,316 ----
        vim9script
        def Outer()
          def g:Inner()
!           echo map([1, 2, 3], (_, v) => v + 1)
          enddef
          g:Inner()
        enddef
***************
*** 509,519 ****
  enddef
  
  def Test_call_lambda_args()
!   CheckDefFailure(['echo {i -> 0}()'],
!                   'E119: Not enough arguments for function: {i -> 0}()')
  
    var lines =<< trim END
!       var Ref = {x: number, y: number -> x + y}
        echo Ref(1, 'x')
    END
    CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number 
but got string')
--- 509,519 ----
  enddef
  
  def Test_call_lambda_args()
!   CheckDefFailure(['echo ((i) => 0)()'],
!                   'E119: Not enough arguments for function: ((i) => 0)()')
  
    var lines =<< trim END
!       var Ref = (x: number, y: number) => x + y
        echo Ref(1, 'x')
    END
    CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number 
but got string')
***************
*** 522,528 ****
  def Test_lambda_uses_assigned_var()
    CheckDefSuccess([
          'var x: any = "aaa"'
!         'x = filter(["bbb"], {_, v -> v =~ x})'])
  enddef
  
  " Default arg and varargs
--- 522,528 ----
  def Test_lambda_uses_assigned_var()
    CheckDefSuccess([
          'var x: any = "aaa"'
!         'x = filter(["bbb"], (_, v) => v =~ x)'])
  enddef
  
  " Default arg and varargs
***************
*** 1413,1424 ****
  
  def Test_closure_simple()
    var local = 'some '
!   RefFunc({s -> local .. s})->assert_equal('some more')
  enddef
  
  def MakeRef()
    var local = 'some '
!   g:Ref = {s -> local .. s}
  enddef
  
  def Test_closure_ref_after_return()
--- 1413,1424 ----
  
  def Test_closure_simple()
    var local = 'some '
!   RefFunc((s) => local .. s)->assert_equal('some more')
  enddef
  
  def MakeRef()
    var local = 'some '
!   g:Ref = (s) => local .. s
  enddef
  
  def Test_closure_ref_after_return()
***************
*** 1429,1436 ****
  
  def MakeTwoRefs()
    var local = ['some']
!   g:Extend = {s -> local->add(s)}
!   g:Read = {-> local}
  enddef
  
  def Test_closure_two_refs()
--- 1429,1436 ----
  
  def MakeTwoRefs()
    var local = ['some']
!   g:Extend = (s) => local->add(s)
!   g:Read = () => local
  enddef
  
  def Test_closure_two_refs()
***************
*** 1467,1478 ****
  
  def MakeArgRefs(theArg: string)
    var local = 'loc_val'
!   g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
  enddef
  
  def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
    var local = 'the_loc'
!   g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
  enddef
  
  def Test_closure_using_argument()
--- 1467,1478 ----
  
  def MakeArgRefs(theArg: string)
    var local = 'loc_val'
!   g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
  enddef
  
  def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
    var local = 'the_loc'
!   g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
  enddef
  
  def Test_closure_using_argument()
***************
*** 1526,1532 ****
  
  def Test_call_closure_not_compiled()
    var text = 'text'
!   g:Ref = {s ->  s .. text}
    GetResult(g:Ref)->assert_equal('sometext')
  enddef
  
--- 1526,1532 ----
  
  def Test_call_closure_not_compiled()
    var text = 'text'
!   g:Ref = (s) =>  s .. text
    GetResult(g:Ref)->assert_equal('sometext')
  enddef
  
***************
*** 1536,1542 ****
      def Func()
        var name = 0
        for i in range(2)
!           timer_start(0, {-> name})
        endfor
      enddef
      Func()
--- 1536,1542 ----
      def Func()
        var name = 0
        for i in range(2)
!           timer_start(0, () => name)
        endfor
      enddef
      Func()
***************
*** 1549,1556 ****
        vim9script
        def Func()
          var x = 'hello'
!         var Closure = {-> x}
!         g:Myclosure = {-> Closure()}
        enddef
        Func()
        assert_equal('hello', g:Myclosure())
--- 1549,1556 ----
        vim9script
        def Func()
          var x = 'hello'
!         var Closure = () => x
!         g:Myclosure = () => Closure()
        enddef
        Func()
        assert_equal('hello', g:Myclosure())
***************
*** 1565,1571 ****
        FuncB(0)
      enddef
      def FuncB(n: number): list<string>
!       return map([0], {_, v -> n})
      enddef
      FuncA()
    END
--- 1565,1571 ----
        FuncB(0)
      enddef
      def FuncB(n: number): list<string>
!       return map([0], (_, v) => n)
      enddef
      FuncA()
    END
***************
*** 1642,1649 ****
      vim9script
      def Func()
        var x = 4
!       var Lambda1 = {-> 7}
!       var Lambda2 = {-> [Lambda1(), x]}
        var res = Lambda2()
        assert_equal([7, 4], res)
      enddef
--- 1642,1649 ----
      vim9script
      def Func()
        var x = 4
!       var Lambda1 = () => 7
!       var Lambda2 = () => [Lambda1(), x]
        var res = Lambda2()
        assert_equal([7, 4], res)
      enddef
***************
*** 1653,1660 ****
  enddef
  
  def Shadowed(): list<number>
!   var FuncList: list<func: number> = [{ -> 42}]
!   return FuncList->map({_, Shadowed -> Shadowed()})
  enddef
  
  def Test_lambda_arg_shadows_func()
--- 1653,1660 ----
  enddef
  
  def Shadowed(): list<number>
!   var FuncList: list<func: number> = [() => 42]
!   return FuncList->map((_, Shadowed) => Shadowed())
  enddef
  
  def Test_lambda_arg_shadows_func()
***************
*** 1676,1690 ****
    var lines =<< trim END
        vim9script
        var script = 'test'
!       assert_equal(['test'], map(['one'], {-> script}))
    END
    CheckScriptSuccess(lines)
  enddef
  
  def Line_continuation_in_lambda(): list<string>
    var x = range(97, 100)
!       ->map({_, v -> nr2char(v)
!           ->toupper()})
        ->reverse()
    return x
  enddef
--- 1676,1690 ----
    var lines =<< trim END
        vim9script
        var script = 'test'
!       assert_equal(['test'], map(['one'], () => script))
    END
    CheckScriptSuccess(lines)
  enddef
  
  def Line_continuation_in_lambda(): list<string>
    var x = range(97, 100)
!       ->map((_, v) => nr2char(v)
!           ->toupper())
        ->reverse()
    return x
  enddef
***************
*** 1772,1782 ****
  enddef
  
  def TreeWalk(dir: string): list<any>
!   return readdir(dir)->map({_, val ->
              fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
                 ? {[val]: TreeWalk(dir .. '/' .. val)}
                 : val
!              })
  enddef
  
  def Test_closure_in_map()
--- 1772,1782 ----
  enddef
  
  def TreeWalk(dir: string): list<any>
!   return readdir(dir)->map((_, val) =>
              fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
                 ? {[val]: TreeWalk(dir .. '/' .. val)}
                 : val
!              )
  enddef
  
  def Test_closure_in_map()
***************
*** 1890,1896 ****
          var x = ['a', 'b', 'c']
          if 1
            var y = 'x'
!           map(x, {-> y})
          endif
          var z = x
          assert_equal(['x', 'x', 'x'], z)
--- 1890,1896 ----
          var x = ['a', 'b', 'c']
          if 1
            var y = 'x'
!           map(x, () => y)
          endif
          var z = x
          assert_equal(['x', 'x', 'x'], z)
***************
*** 1922,1928 ****
        vim9script
        au BufWinLeave * #
        def Func()
!           popup_menu('', {callback: {-> popup_create('', {})->popup_close()}})
            eval [][0]
        enddef
        nno <F3> <cmd>call <sid>Func()<cr>
--- 1922,1928 ----
        vim9script
        au BufWinLeave * #
        def Func()
!           popup_menu('', {callback: () => popup_create('', 
{})->popup_close()})
            eval [][0]
        enddef
        nno <F3> <cmd>call <sid>Func()<cr>
***************
*** 2014,2020 ****
        var d: dict<any>
        def Func()
          try
!           g:result = map([], {_, v -> {}[v]})->join() .. d['']
          catch
          endtry
        enddef
--- 2014,2020 ----
        var d: dict<any>
        def Func()
          try
!           g:result = map([], (_, v) => ({}[v]))->join() .. d['']
          catch
          endtry
        enddef
*** ../vim-8.2.2256/src/testdir/test_vim9_script.vim    2020-12-27 
13:39:44.659044653 +0100
--- src/testdir/test_vim9_script.vim    2020-12-31 20:37:33.182636132 +0100
***************
*** 1162,1168 ****
  
    var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
                  rows: 6, wait_for_ruler: 0})
!   WaitForAssert({-> assert_match('^E1094:', term_getline(buf, 5))})
  
    delete('XexportCmd.vim')
    StopVimInTerminal(buf)
--- 1162,1168 ----
  
    var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
                  rows: 6, wait_for_ruler: 0})
!   WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
  
    delete('XexportCmd.vim')
    StopVimInTerminal(buf)
***************
*** 3064,3070 ****
    # define Afunc() on the command line
    term_sendkeys(buf, ":def Afunc()\<CR>Bfunc()\<CR>enddef\<CR>")
    term_sendkeys(buf, ":call CheckAndQuit()\<CR>")
!   WaitForAssert({-> assert_equal(['errors: []'], readfile('Xdidcmd'))})
  
    call StopVimInTerminal(buf)
    delete('XcallFunc')
--- 3064,3070 ----
    # define Afunc() on the command line
    term_sendkeys(buf, ":def Afunc()\<CR>Bfunc()\<CR>enddef\<CR>")
    term_sendkeys(buf, ":call CheckAndQuit()\<CR>")
!   WaitForAssert(() => assert_equal(['errors: []'], readfile('Xdidcmd')))
  
    call StopVimInTerminal(buf)
    delete('XcallFunc')
*** ../vim-8.2.2256/src/version.c       2020-12-31 18:28:13.706927452 +0100
--- src/version.c       2020-12-31 21:26:22.375737009 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2257,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
60. As your car crashes through the guardrail on a mountain road, your first
    instinct is to search for the "back" button.

 /// 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/202012312029.0BVKTIT81331154%40masaka.moolenaar.net.

Raspunde prin e-mail lui