Patch 8.2.3704
Problem:    Vim9: cannot use a list declaration in a :def function.
Solution:   Make it work.
Files:      runtime/doc/vim9.txt, src/vim9compile.c, src/errors.h,
            src/testdir/test_vim9_assign.vim


*** ../vim-8.2.3703/runtime/doc/vim9.txt        2021-10-13 15:04:28.859631740 
+0100
--- runtime/doc/vim9.txt        2021-11-30 16:13:01.140854022 +0000
***************
*** 360,371 ****
  To ignore any remaining items: >
        [a, b; _] = longList
  
- <                                                     *E1092*
  Declaring more than one variable at a time, using the unpack notation, is
! currently not supported: >
!       var [v1, v2] = GetValues()  # Error!
! That is because the type needs to be inferred from the list item type, which
! isn't that easy.
  
  
  Constants ~
--- 421,431 ----
  To ignore any remaining items: >
        [a, b; _] = longList
  
  Declaring more than one variable at a time, using the unpack notation, is
! possible.  Each variable can have a type or infer it from the value: >
!       var [v1: number, v2] = GetValues()
! Use this only when there is a list with values, declaring one variable per
! line is much easier to read and change later.
  
  
  Constants ~
*** ../vim-8.2.3703/src/vim9compile.c   2021-11-29 22:02:08.108571662 +0000
--- src/vim9compile.c   2021-11-30 15:58:17.631361229 +0000
***************
*** 144,149 ****
--- 144,150 ----
                                      // any "[expr]" or ".name"
      char_u        *lhs_dest_end;  // end of the destination, including
                                    // "[expr]" or ".name".
+     char_u        *lhs_end;       // end including any type
  
      int                   lhs_has_index;  // has "[expr]" or ".name"
  
***************
*** 6299,6304 ****
--- 6300,6306 ----
        --lhs->lhs_dest_end;
      if (is_decl && var_end == var_start + 2 && var_end[-1] == ':')
        --var_end;
+     lhs->lhs_end = lhs->lhs_dest_end;
  
      // compute the length of the destination without "[expr]" or ".name"
      lhs->lhs_varlen = var_end - var_start;
***************
*** 6435,6441 ****
        }
      }
  
!     // handle "a:name" as a name, not index "name" on "a"
      if (lhs->lhs_varlen > 1 || var_start[lhs->lhs_varlen] != ':')
        var_end = lhs->lhs_dest_end;
  
--- 6437,6443 ----
        }
      }
  
!     // handle "a:name" as a name, not index "name" in "a"
      if (lhs->lhs_varlen > 1 || var_start[lhs->lhs_varlen] != ':')
        var_end = lhs->lhs_dest_end;
  
***************
*** 6456,6461 ****
--- 6458,6464 ----
            if (lhs->lhs_type == NULL)
                return FAIL;
            lhs->lhs_has_type = TRUE;
+           lhs->lhs_end = p;
        }
        else if (lhs->lhs_lvar != NULL)
            lhs->lhs_type = lhs->lhs_lvar->lv_type;
***************
*** 6896,6908 ****
      if (p == NULL)
        return *arg == '[' ? arg : NULL;
  
-     if (var_count > 0 && is_decl)
-     {
-       // TODO: should we allow this, and figure out type inference from list
-       // members?
-       emsg(_(e_cannot_use_list_for_declaration));
-       return NULL;
-     }
      lhs.lhs_name = NULL;
  
      sp = p;
--- 6899,6904 ----
***************
*** 7330,7336 ****
        cctx->ctx_lnum = save_lnum;
  
        if (var_idx + 1 < var_count)
!           var_start = skipwhite(lhs.lhs_dest_end + 1);
      }
  
      // For "[var, var] = expr" drop the "expr" value.
--- 7326,7332 ----
        cctx->ctx_lnum = save_lnum;
  
        if (var_idx + 1 < var_count)
!           var_start = skipwhite(lhs.lhs_end + 1);
      }
  
      // For "[var, var] = expr" drop the "expr" value.
*** ../vim-8.2.3703/src/errors.h        2021-11-29 10:36:15.916827518 +0000
--- src/errors.h        2021-11-30 15:36:39.680249957 +0000
***************
*** 366,373 ****
        INIT(= N_("E1090: Cannot assign to argument %s"));
  EXTERN char e_function_is_not_compiled_str[]
        INIT(= N_("E1091: Function is not compiled: %s"));
! EXTERN char e_cannot_use_list_for_declaration[]
!       INIT(= N_("E1092: Cannot use a list for a declaration"));
  EXTERN char e_expected_nr_items_but_got_nr[]
        INIT(= N_("E1093: Expected %d items but got %d"));
  EXTERN char e_import_can_only_be_used_in_script[]
--- 366,372 ----
        INIT(= N_("E1090: Cannot assign to argument %s"));
  EXTERN char e_function_is_not_compiled_str[]
        INIT(= N_("E1091: Function is not compiled: %s"));
! // E1092 unused
  EXTERN char e_expected_nr_items_but_got_nr[]
        INIT(= N_("E1093: Expected %d items but got %d"));
  EXTERN char e_import_can_only_be_used_in_script[]
*** ../vim-8.2.3703/src/testdir/test_vim9_assign.vim    2021-11-29 
16:01:45.384711994 +0000
--- src/testdir/test_vim9_assign.vim    2021-11-30 16:09:45.301378152 +0000
***************
*** 732,738 ****
    assert_equal(['sdf', 'asdf', 'end'], list3)
  
    CheckDefExecFailure(['var ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:')
-   CheckDefExecFailure(['var [v1, v2] = [1, 2]'], 'E1092:')
  
    # type becomes list<any>
    var somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
--- 732,737 ----
***************
*** 753,758 ****
--- 752,811 ----
    CheckDefExecAndScriptFailure(lines, 'E1012:', 5)
  enddef
  
+ def Test_list_declaration()
+   var [v1, v2] = [1, 2]
+   v1 += 3
+   assert_equal(4, v1)
+   v2 *= 3
+   assert_equal(6, v2)
+ 
+   var lines =<< trim END
+       var [v1, v2] = [1]
+   END
+   CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 1', 
'E688:')
+   lines =<< trim END
+       var testlist = [1]
+       var [v1, v2] = testlist
+   END
+   CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 1', 
'E688:')
+   lines =<< trim END
+       var [v1, v2] = [1, 2, 3]
+   END
+   CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 3', 
'E687:')
+   lines =<< trim END
+       var testlist = [1, 2, 3]
+       var [v1, v2] = testlist
+   END
+   CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 3', 
'E687:')
+ 
+   var [vnr, vstr] = [123, 'text']
+   vnr += 3
+   assert_equal(126, vnr)
+   vstr ..= 'end'
+   assert_equal('textend', vstr)
+ 
+   var [vnr2: number, vstr2: string] = [123, 'text']
+   vnr2 += 3
+   assert_equal(126, vnr2)
+   vstr2 ..= 'end'
+   assert_equal('textend', vstr2)
+ 
+   var [vnr3: number; vlist: list<string>] = [123, 'foo', 'bar']
+   vnr3 += 5
+   assert_equal(128, vnr3)
+   assert_equal(['foo', 'bar'], vlist)
+ 
+   lines =<< trim END
+       var [vnr2: number, vstr2: number] = [123, 'text']
+   END
+   CheckDefExecAndScriptFailure2(lines, 'E1163: Variable 2: type mismatch, 
expected number but got string', 'E1012: Type mismatch; expected number but got 
string')
+   lines =<< trim END
+       var testlist = [234, 'text']
+       var [vnr2: number, vstr2: number] = testlist
+   END
+   CheckDefExecAndScriptFailure2(lines, 'E1163: Variable 2: type mismatch, 
expected number but got string', 'E1012: Type mismatch; expected number but got 
string')
+ enddef
+ 
  def PartFuncBool(b: bool): string
    return 'done'
  enddef
*** ../vim-8.2.3703/src/version.c       2021-11-30 13:02:55.120889114 +0000
--- src/version.c       2021-11-30 15:36:15.924291307 +0000
***************
*** 755,756 ****
--- 755,758 ----
  {   /* Add new patch number below this line */
+ /**/
+     3704,
  /**/

-- 
Why I like vim:
> I like VIM because, when I ask a question in this newsgroup, I get a
> one-line answer.  With xemacs, I get a 1Kb lisp script with bugs in it ;-)

 /// 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/20211130161526.62B1E1C4FBE%40moolenaar.net.

Raspunde prin e-mail lui