Patch 8.2.4529
Problem:    Vim9: comparing partial with function fails.
Solution:   Support this comparison.  Avoid a crash. (closes #9909)
            Add more test cases.
Files:      src/vim9instr.c, src/userfunc.c, src/vim9type.c,
            src/testdir/test_vim9_builtin.vim, src/testdir/test_vim9_expr.vim,
            src/testdir/test_vim9_func.vim, src/testdir/test_vimscript.vim


*** ../vim-8.2.4528/src/vim9instr.c     2022-03-08 13:18:10.809020782 +0000
--- src/vim9instr.c     2022-03-08 18:58:21.949496564 +0000
***************
*** 370,376 ****
      }
      else if (type1 == VAR_ANY || type2 == VAR_ANY
            || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
!             && (type2 == VAR_NUMBER || type2 == VAR_FLOAT)))
        isntype = ISN_COMPAREANY;
      else if (type1 == VAR_SPECIAL || type2 == VAR_SPECIAL)
      {
--- 370,378 ----
      }
      else if (type1 == VAR_ANY || type2 == VAR_ANY
            || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
!                              && (type2 == VAR_NUMBER || type2 == VAR_FLOAT))
!           || (type1 == VAR_FUNC && type2 == VAR_PARTIAL)
!           || (type1 == VAR_PARTIAL && type2 == VAR_FUNC))
        isntype = ISN_COMPAREANY;
      else if (type1 == VAR_SPECIAL || type2 == VAR_SPECIAL)
      {
*** ../vim-8.2.4528/src/userfunc.c      2022-03-08 16:52:18.807756958 +0000
--- src/userfunc.c      2022-03-08 19:16:32.579191126 +0000
***************
*** 5730,5747 ****
  make_partial(dict_T *selfdict_in, typval_T *rettv)
  {
      char_u    *fname;
!     ufunc_T   *fp;
      char_u    fname_buf[FLEN_FIXED + 1];
      int               error;
      dict_T    *selfdict = selfdict_in;
  
!     if (rettv->v_type == VAR_PARTIAL && rettv->vval.v_partial->pt_func != 
NULL)
        fp = rettv->vval.v_partial->pt_func;
      else
      {
        fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
                                              : rettv->vval.v_partial->pt_name;
!       if (fname != NULL)
        {
            char_u      *tofree = NULL;
  
--- 5730,5756 ----
  make_partial(dict_T *selfdict_in, typval_T *rettv)
  {
      char_u    *fname;
!     ufunc_T   *fp = NULL;
      char_u    fname_buf[FLEN_FIXED + 1];
      int               error;
      dict_T    *selfdict = selfdict_in;
  
!     if (rettv->v_type == VAR_PARTIAL  && rettv->vval.v_partial != NULL
!                                    && rettv->vval.v_partial->pt_func != NULL)
        fp = rettv->vval.v_partial->pt_func;
      else
      {
        fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
+                                        : rettv->vval.v_partial == NULL ? NULL
                                              : rettv->vval.v_partial->pt_name;
!       if (fname == NULL)
!       {
!           // There is no point binding a dict to a NULL function, just create
!           // a function reference.
!           rettv->v_type = VAR_FUNC;
!           rettv->vval.v_string = NULL;
!       }
!       else
        {
            char_u      *tofree = NULL;
  
***************
*** 5752,5759 ****
        }
      }
  
!     if ((fp != NULL && (fp->uf_flags & FC_DICT))
!               || (rettv->v_type == VAR_FUNC && rettv->vval.v_string == NULL))
      {
        partial_T       *pt = ALLOC_CLEAR_ONE(partial_T);
  
--- 5761,5767 ----
        }
      }
  
!     if (fp != NULL && (fp->uf_flags & FC_DICT))
      {
        partial_T       *pt = ALLOC_CLEAR_ONE(partial_T);
  
*** ../vim-8.2.4528/src/vim9type.c      2022-03-08 13:18:10.809020782 +0000
--- src/vim9type.c      2022-03-08 19:38:42.740545016 +0000
***************
*** 420,425 ****
--- 420,427 ----
        }
        else
            name = tv->vval.v_string;
+       if (name == NULL && ufunc == NULL)
+           return &t_func_unknown;
        if (name != NULL)
        {
            int idx = find_internal_func(name);
*** ../vim-8.2.4528/src/testdir/test_vim9_builtin.vim   2022-02-23 
21:03:28.913442583 +0000
--- src/testdir/test_vim9_builtin.vim   2022-03-08 19:40:04.756387254 +0000
***************
*** 1687,1692 ****
--- 1687,1693 ----
    endif
    $SOMEENVVAR = 'some'
    assert_equal('some', getenv('SOMEENVVAR'))
+   assert_notequal(null, getenv('SOMEENVVAR'))
    unlet $SOMEENVVAR
    getenv('')->assert_equal(v:null)
  enddef
***************
*** 4398,4404 ****
    if has('float')
      assert_equal('func([unknown], [unknown]): float', 
typename(function('pow')))
    endif
!   assert_equal('func', test_null_partial()->typename())
    assert_equal('list<unknown>', test_null_list()->typename())
    assert_equal('dict<unknown>', test_null_dict()->typename())
    if has('job')
--- 4399,4405 ----
    if has('float')
      assert_equal('func([unknown], [unknown]): float', 
typename(function('pow')))
    endif
!   assert_equal('func(...): unknown', test_null_partial()->typename())
    assert_equal('list<unknown>', test_null_list()->typename())
    assert_equal('dict<unknown>', test_null_dict()->typename())
    if has('job')
*** ../vim-8.2.4528/src/testdir/test_vim9_expr.vim      2022-03-01 
19:23:20.544357315 +0000
--- src/testdir/test_vim9_expr.vim      2022-03-08 19:19:38.126801608 +0000
***************
*** 717,737 ****
--- 717,749 ----
    g:not_null_list = []
    var lines =<< trim END
        assert_true(test_null_blob() == v:null)
+       assert_true(null_blob == null)
        assert_true(v:null == test_null_blob())
+       assert_true(null == null_blob)
        assert_false(test_null_blob() != v:null)
+       assert_false(null_blob != null)
        assert_false(v:null != test_null_blob())
+       assert_false(null != null_blob)
  
        if has('channel')
          assert_true(test_null_channel() == v:null)
+         assert_true(null_channel == null)
          assert_true(v:null == test_null_channel())
+         assert_true(null == null_channel)
          assert_false(test_null_channel() != v:null)
+         assert_false(null_channel != null)
          assert_false(v:null != test_null_channel())
+         assert_false(null != null_channel)
        endif
  
        assert_true(test_null_dict() == v:null)
+       assert_true(null_dict == null)
        assert_true(v:null == test_null_dict())
+       assert_true(null == null_dict)
        assert_false(test_null_dict() != v:null)
+       assert_false(null_dict != null)
        assert_false(v:null != test_null_dict())
+       assert_false(null != null_dict)
  
        assert_true(g:null_dict == v:null)
        assert_true(v:null == g:null_dict)
***************
*** 739,759 ****
--- 751,783 ----
        assert_false(v:null != g:null_dict)
  
        assert_true(test_null_function() == v:null)
+       assert_true(null_function == null)
        assert_true(v:null == test_null_function())
+       assert_true(null == null_function)
        assert_false(test_null_function() != v:null)
+       assert_false(null_function != null)
        assert_false(v:null != test_null_function())
+       assert_false(null != null_function)
  
        if has('job')
          assert_true(test_null_job() == v:null)
+         assert_true(null_job == null)
          assert_true(v:null == test_null_job())
+         assert_true(null == null_job)
          assert_false(test_null_job() != v:null)
+         assert_false(null_job != null)
          assert_false(v:null != test_null_job())
+         assert_false(null != null_job)
        endif
  
        assert_true(test_null_list() == v:null)
+       assert_true(null_list == null)
        assert_true(v:null == test_null_list())
+       assert_true(null == null_list)
        assert_false(test_null_list() != v:null)
+       assert_false(null_list != null)
        assert_false(v:null != test_null_list())
+       assert_false(null != null_list)
  
        assert_false(g:not_null_list == v:null)
        assert_false(v:null == g:not_null_list)
***************
*** 761,779 ****
--- 785,817 ----
        assert_true(v:null != g:not_null_list)
  
        assert_true(test_null_partial() == v:null)
+       assert_true(null_partial == null)
        assert_true(v:null == test_null_partial())
+       assert_true(null == null_partial)
        assert_false(test_null_partial() != v:null)
+       assert_false(null_partial != null)
        assert_false(v:null != test_null_partial())
+       assert_false(null != null_partial)
  
        assert_true(test_null_string() == v:null)
+       assert_true(null_string == null)
        assert_true(v:null == test_null_string())
+       assert_true(null == null_string)
        assert_false(test_null_string() != v:null)
+       assert_false(null_string != null)
        assert_false(v:null != test_null_string())
+       assert_false(null != null_string)
    END
    v9.CheckDefAndScriptSuccess(lines)
    unlet g:null_dict
    unlet g:not_null_list
  
+   lines =<< trim END
+       var d: dict<func> = {f: null_function}
+       assert_equal(null_function, d.f)
+   END
+   v9.CheckDefAndScriptSuccess(lines)
+ 
    v9.CheckDefAndScriptFailure(['echo 123 == v:null'], 'E1072: Cannot compare 
number with special')
    v9.CheckDefAndScriptFailure(['echo v:null == 123'], 'E1072: Cannot compare 
special with number')
    v9.CheckDefAndScriptFailure(['echo 123 != v:null'], 'E1072: Cannot compare 
number with special')
*** ../vim-8.2.4528/src/testdir/test_vim9_func.vim      2022-03-08 
16:52:18.807756958 +0000
--- src/testdir/test_vim9_func.vim      2022-03-08 19:27:47.821817178 +0000
***************
*** 3341,3347 ****
    var lines =<< trim END
        var d: dict<func> = {f: null_function}
        var Ref = d.f
!       assert_equal('func', typename(Ref))
    END
    v9.CheckDefAndScriptSuccess(lines)
  enddef
--- 3341,3347 ----
    var lines =<< trim END
        var d: dict<func> = {f: null_function}
        var Ref = d.f
!       assert_equal('func(...): unknown', typename(Ref))
    END
    v9.CheckDefAndScriptSuccess(lines)
  enddef
*** ../vim-8.2.4528/src/testdir/test_vimscript.vim      2022-03-02 
13:13:26.475857972 +0000
--- src/testdir/test_vimscript.vim      2022-03-02 14:46:33.321695479 +0000
***************
*** 6571,6576 ****
--- 6571,6579 ----
      call assert_false(v:true is 1)
      call assert_false(v:true is v:false)
      call assert_false(v:none is 0)
+     call assert_false(v:none is [])
+     call assert_false(v:none is {})
+     call assert_false(v:none is 'text')
      call assert_false(v:null is 0)
      call assert_false(v:null is v:none)
  
*** ../vim-8.2.4528/src/version.c       2022-03-08 16:52:18.807756958 +0000
--- src/version.c       2022-03-08 19:00:28.957245068 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4529,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
207. You're given one phone call in prison and you ask them for a laptop.

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220308194448.67C681C08CF%40moolenaar.net.

Raspunde prin e-mail lui