summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-03-12 21:28:22 +0000
committerBram Moolenaar <Bram@vim.org>2022-03-12 21:28:22 +0000
commitbadf04f5c219743cd6645ff1f1fe88badf4af4c5 (patch)
treee85bb132e215f99c74116378d0bf0cd85734dfd8
parent8b530b3158cbd3aee2ad9cad8e7b7964faabb51e (diff)
downloadvim-git-badf04f5c219743cd6645ff1f1fe88badf4af4c5.tar.gz
patch 8.2.4554: Vim9: using null values not sufficiently testedv8.2.4554
Problem: Vim9: using null values not sufficiently tested. Solution: Add more tests. Fix uncovered problem.
-rw-r--r--src/testdir/test_vim9_assign.vim16
-rw-r--r--src/testdir/test_vim9_func.vim108
-rw-r--r--src/version.c2
-rw-r--r--src/vim9type.c13
4 files changed, 139 insertions, 0 deletions
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 21a39e1f6..37ca2aee4 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -342,6 +342,22 @@ def Test_null_values()
endif
var d: dict<func> = {a: function('tr'), b: null_function}
+
+ var bl: list<blob> = [0z12, null_blob]
+ var dnl: list<dict<number>> = [{a: 1}, null_dict]
+ var dsl: list<dict<string>> = [{a: 'x'}, null_dict]
+ var lnl: list<list<number>> = [[1], null_list]
+ var lsl: list<list<string>> = [['x'], null_list]
+ def Len(v: string): number
+ return len(v)
+ enddef
+ var Ffl: list<func(string): number> = [Len, null_function]
+ var Fpl: list<func(string): number> = [Len, null_partial]
+ var sl: list<string> = ['x', null_string]
+ if has('job')
+ var jl: list<job> = [null_job]
+ var cl: list<channel> = [null_channel]
+ endif
END
v9.CheckDefAndScriptSuccess(lines)
enddef
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 43fc68ef7..8c99ad400 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -3759,6 +3759,114 @@ def Test_check_func_arg_types()
v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
enddef
+def Test_call_func_with_null()
+ var lines =<< trim END
+ def Fstring(v: string)
+ assert_equal(null_string, v)
+ enddef
+ Fstring(null_string)
+ def Fblob(v: blob)
+ assert_equal(null_blob, v)
+ enddef
+ Fblob(null_blob)
+ def Flist(v: list<number>)
+ assert_equal(null_list, v)
+ enddef
+ Flist(null_list)
+ def Fdict(v: dict<number>)
+ assert_equal(null_dict, v)
+ enddef
+ Fdict(null_dict)
+ def Ffunc(Fv: func(number): number)
+ assert_equal(null_function, Fv)
+ enddef
+ Ffunc(null_function)
+ if has('channel')
+ def Fchannel(v: channel)
+ assert_equal(null_channel, v)
+ enddef
+ Fchannel(null_channel)
+ def Fjob(v: job)
+ assert_equal(null_job, v)
+ enddef
+ Fjob(null_job)
+ endif
+ END
+ v9.CheckDefAndScriptSuccess(lines)
+enddef
+
+def Test_null_default_argument()
+ var lines =<< trim END
+ def Fstring(v: string = null_string)
+ assert_equal(null_string, v)
+ enddef
+ Fstring()
+ def Fblob(v: blob = null_blob)
+ assert_equal(null_blob, v)
+ enddef
+ Fblob()
+ def Flist(v: list<number> = null_list)
+ assert_equal(null_list, v)
+ enddef
+ Flist()
+ def Fdict(v: dict<number> = null_dict)
+ assert_equal(null_dict, v)
+ enddef
+ Fdict()
+ def Ffunc(Fv: func(number): number = null_function)
+ assert_equal(null_function, Fv)
+ enddef
+ Ffunc()
+ if has('channel')
+ def Fchannel(v: channel = null_channel)
+ assert_equal(null_channel, v)
+ enddef
+ Fchannel()
+ def Fjob(v: job = null_job)
+ assert_equal(null_job, v)
+ enddef
+ Fjob()
+ endif
+ END
+ v9.CheckDefAndScriptSuccess(lines)
+enddef
+
+def Test_null_return()
+ var lines =<< trim END
+ def Fstring(): string
+ return null_string
+ enddef
+ assert_equal(null_string, Fstring())
+ def Fblob(): blob
+ return null_blob
+ enddef
+ assert_equal(null_blob, Fblob())
+ def Flist(): list<number>
+ return null_list
+ enddef
+ assert_equal(null_list, Flist())
+ def Fdict(): dict<number>
+ return null_dict
+ enddef
+ assert_equal(null_dict, Fdict())
+ def Ffunc(): func(number): number
+ return null_function
+ enddef
+ assert_equal(null_function, Ffunc())
+ if has('channel')
+ def Fchannel(): channel
+ return null_channel
+ enddef
+ assert_equal(null_channel, Fchannel())
+ def Fjob(): job
+ return null_job
+ enddef
+ assert_equal(null_job, Fjob())
+ endif
+ END
+ v9.CheckDefAndScriptSuccess(lines)
+enddef
+
def Test_list_any_type_checked()
var lines =<< trim END
vim9script
diff --git a/src/version.c b/src/version.c
index 0c90e2dab..bdd9dd8f3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4554,
+/**/
4553,
/**/
4552,
diff --git a/src/vim9type.c b/src/vim9type.c
index 6a44c7b7c..b6687b089 100644
--- a/src/vim9type.c
+++ b/src/vim9type.c
@@ -1235,6 +1235,19 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
{
type_T *common;
+ // When one of the types is t_func_unknown return the other one.
+ // Useful if a list or dict item is null_func.
+ if (type1 == &t_func_unknown)
+ {
+ *dest = type2;
+ return;
+ }
+ if (type2 == &t_func_unknown)
+ {
+ *dest = type1;
+ return;
+ }
+
common_type(type1->tt_member, type2->tt_member, &common, type_gap);
if (type1->tt_argcount == type2->tt_argcount
&& type1->tt_argcount >= 0)