Patch 8.2.3682
Problem:    Vim9: assigning to a script variable drops the required type.
Solution:   Lookup the type of the variable and use it. (closes #9219)
Files:      src/evalvars.c, src/vim9script.c, src/proto/vim9script.pro,
            src/testdir/test_vim9_assign.vim


*** ../vim-8.2.3681/src/evalvars.c      2021-11-22 21:58:37.918668436 +0000
--- src/evalvars.c      2021-11-26 17:35:30.548872169 +0000
***************
*** 3206,3218 ****
      void
  set_var_const(
      char_u    *name,
!     type_T    *type,
      typval_T  *tv_arg,
      int               copy,       // make copy of value in "tv"
      int               flags_arg,  // ASSIGN_CONST, ASSIGN_FINAL, etc.
      int               var_idx)    // index for ":let [a, b] = list"
  {
      typval_T  *tv = tv_arg;
      typval_T  bool_tv;
      dictitem_T        *di;
      typval_T  *dest_tv = NULL;
--- 3206,3219 ----
      void
  set_var_const(
      char_u    *name,
!     type_T    *type_arg,
      typval_T  *tv_arg,
      int               copy,       // make copy of value in "tv"
      int               flags_arg,  // ASSIGN_CONST, ASSIGN_FINAL, etc.
      int               var_idx)    // index for ":let [a, b] = list"
  {
      typval_T  *tv = tv_arg;
+     type_T    *type = type_arg;
      typval_T  bool_tv;
      dictitem_T        *di;
      typval_T  *dest_tv = NULL;
***************
*** 3334,3346 ****
                if (var_in_vim9script && (flags & ASSIGN_FOR_LOOP) == 0)
                {
                    where_T where = WHERE_INIT;
  
!                   // check the type and adjust to bool if needed
!                   where.wt_index = var_idx;
!                   where.wt_variable = TRUE;
!                   if (check_script_var_type(&di->di_tv, tv, name, where)
!                                                                      == FAIL)
!                       goto failed;
                }
  
                if ((flags & ASSIGN_FOR_LOOP) == 0
--- 3335,3352 ----
                if (var_in_vim9script && (flags & ASSIGN_FOR_LOOP) == 0)
                {
                    where_T where = WHERE_INIT;
+                   svar_T  *sv = find_typval_in_script(&di->di_tv);
  
!                   if (sv != NULL)
!                   {
!                       // check the type and adjust to bool if needed
!                       where.wt_index = var_idx;
!                       where.wt_variable = TRUE;
!                       if (check_script_var_type(sv, tv, name, where) == FAIL)
!                           goto failed;
!                       if (type == NULL)
!                           type = sv->sv_type;
!                   }
                }
  
                if ((flags & ASSIGN_FOR_LOOP) == 0
*** ../vim-8.2.3681/src/vim9script.c    2021-10-15 00:18:32.890481145 +0100
--- src/vim9script.c    2021-11-26 17:29:27.141126221 +0000
***************
*** 999,1033 ****
   */
      int
  check_script_var_type(
!       typval_T    *dest,
        typval_T    *value,
        char_u      *name,
        where_T     where)
  {
-     svar_T  *sv = find_typval_in_script(dest);
      int           ret;
  
!     if (sv != NULL)
      {
!       if (sv->sv_const != 0)
!       {
!           semsg(_(e_cannot_change_readonly_variable_str), name);
!           return FAIL;
!       }
!       ret = check_typval_type(sv->sv_type, value, where);
!       if (ret == OK && need_convert_to_bool(sv->sv_type, value))
!       {
!           int val = tv2bool(value);
! 
!           clear_tv(value);
!           value->v_type = VAR_BOOL;
!           value->v_lock = 0;
!           value->vval.v_number = val ? VVAL_TRUE : VVAL_FALSE;
!       }
!       return ret;
      }
  
!     return OK; // not really
  }
  
  // words that cannot be used as a variable
--- 999,1027 ----
   */
      int
  check_script_var_type(
!       svar_T      *sv,
        typval_T    *value,
        char_u      *name,
        where_T     where)
  {
      int           ret;
  
!     if (sv->sv_const != 0)
      {
!       semsg(_(e_cannot_change_readonly_variable_str), name);
!       return FAIL;
      }
+     ret = check_typval_type(sv->sv_type, value, where);
+     if (ret == OK && need_convert_to_bool(sv->sv_type, value))
+     {
+       int     val = tv2bool(value);
  
!       clear_tv(value);
!       value->v_type = VAR_BOOL;
!       value->v_lock = 0;
!       value->vval.v_number = val ? VVAL_TRUE : VVAL_FALSE;
!     }
!     return ret;
  }
  
  // words that cannot be used as a variable
*** ../vim-8.2.3681/src/proto/vim9script.pro    2021-08-15 12:49:38.122905579 
+0100
--- src/proto/vim9script.pro    2021-11-26 17:30:54.705081599 +0000
***************
*** 16,21 ****
  void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T 
*tv, type_T **type, int do_member);
  void hide_script_var(scriptitem_T *si, int idx, int func_defined);
  svar_T *find_typval_in_script(typval_T *dest);
! int check_script_var_type(typval_T *dest, typval_T *value, char_u *name, 
where_T where);
  int check_reserved_name(char_u *name);
  /* vim: set ft=c : */
--- 16,21 ----
  void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T 
*tv, type_T **type, int do_member);
  void hide_script_var(scriptitem_T *si, int idx, int func_defined);
  svar_T *find_typval_in_script(typval_T *dest);
! int check_script_var_type(svar_T *sv, typval_T *value, char_u *name, where_T 
where);
  int check_reserved_name(char_u *name);
  /* vim: set ft=c : */
*** ../vim-8.2.3681/src/testdir/test_vim9_assign.vim    2021-09-09 
22:01:10.506519642 +0100
--- src/testdir/test_vim9_assign.vim    2021-11-26 17:34:44.768912804 +0000
***************
*** 322,327 ****
--- 322,337 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
+ def Test_assign_keep_type()
+   var lines =<< trim END
+       vim9script
+       var l: list<number> = [123]
+       l = [123]
+       l->add('string')
+   END
+   CheckScriptFailure(lines, 'E1012:', 4)
+ enddef
+ 
  def Test_assign_unpack()
    var lines =<< trim END
      var v1: number
*** ../vim-8.2.3681/src/version.c       2021-11-26 15:57:14.310265430 +0000
--- src/version.c       2021-11-26 17:27:27.769164014 +0000
***************
*** 759,760 ****
--- 759,762 ----
  {   /* Add new patch number below this line */
+ /**/
+     3682,
  /**/

-- 
Why is "abbreviation" such a long word?

 /// 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/20211126173734.64FF71C1151%40moolenaar.net.

Raspunde prin e-mail lui