]> granicus.if.org Git - vim/commitdiff
patch 8.2.3872: Vim9: finddir() and uniq() return types can be more specific v8.2.3872
authorBram Moolenaar <Bram@vim.org>
Wed, 22 Dec 2021 18:45:37 +0000 (18:45 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 22 Dec 2021 18:45:37 +0000 (18:45 +0000)
Problem:    Vim9: finddir() and uniq() return types can be more specific.
Solution:   Adjust the return type.

src/evalfunc.c
src/testdir/test_vim9_builtin.vim
src/testdir/vim9.vim
src/version.c

index 39b94deb977c6a40d9b870c5268213c48863fa6e..f42650ebb23c12b7ae767eae4554d8b0efd84d10 100644 (file)
@@ -1033,6 +1033,15 @@ ret_first_cont(int argcount, type_T **argtypes)
     }
     return &t_any;
 }
+// for finddir()
+    static type_T *
+ret_finddir(int argcount, type_T **argtypes UNUSED)
+{
+    if (argcount < 3)
+       return &t_string;
+    // Depending on the count would be a string or a list of strings.
+    return &t_any;
+}
 
 /*
  * Used for getqflist(): returns list if there is no argument, dict if there is
@@ -1431,7 +1440,7 @@ static funcentry_T global_functions[] =
     {"filter",         2, 2, FEARG_1,      arg2_mapfilter,
                        ret_first_arg,      f_filter},
     {"finddir",                1, 3, FEARG_1,      arg3_string_string_number,
-                       ret_any,            f_finddir},
+                       ret_finddir,        f_finddir},
     {"findfile",       1, 3, FEARG_1,      arg3_string_string_number,
                        ret_any,            f_findfile},
     {"flatten",                1, 2, FEARG_1,      arg2_list_any_number,
@@ -2291,7 +2300,7 @@ static funcentry_T global_functions[] =
     {"undotree",       0, 0, 0,            NULL,
                        ret_dict_any,       f_undotree},
     {"uniq",           1, 3, FEARG_1,      arg13_sortuniq,
-                       ret_list_any,       f_uniq},
+                       ret_first_arg,      f_uniq},
     {"values",         1, 1, FEARG_1,      arg1_dict_any,
                        ret_list_any,       f_values},
     {"virtcol",                1, 1, FEARG_1,      arg1_string_or_list_any,
index 58194bad675f8b28f8e195c23f82c78102ff6a15..298a3be5228f22656266983eaab5cb98da4595dc 100644 (file)
@@ -1110,6 +1110,11 @@ def Test_finddir()
   CheckDefAndScriptFailure(['finddir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 2'])
   CheckDefAndScriptFailure(['finddir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
   finddir('abc', '')->assert_equal('')
+
+  CheckDefFailure(['var s: list<string> = finddir("foo")'], 'E1012: Type mismatch; expected list<string> but got string')
+  CheckDefFailure(['var s: list<string> = finddir("foo", "path")'], 'E1012: Type mismatch; expected list<string> but got string')
+  # with third argument only runtime type checking
+  CheckDefCompileSuccess(['var s: list<string> = finddir("foo", "path", 1)'])
 enddef
 
 def Test_findfile()
@@ -4036,6 +4041,8 @@ enddef
 def Test_uniq()
   CheckDefAndScriptFailure(['uniq("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
   CheckDefAndScriptFailure(['uniq([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+
+  CheckDefFailure(['var l: list<number> = uniq(["a", "b"])'], 'E1012: Type mismatch; expected list<number> but got list<string>')
 enddef
 
 def Test_values()
index a6e1e67516a680d78605ed6df0484ce210fb2058..89f3c791786bfadb0cbbd632274ddc88b9f03199 100644 (file)
@@ -3,7 +3,7 @@
 " Use a different file name for each run.
 let s:sequence = 1
 
-" Check that "lines" inside a ":def" function has no error.
+" Check that "lines" inside a ":def" function has no error when called.
 func CheckDefSuccess(lines)
   let cwd = getcwd()
   let fname = 'XdefSuccess' .. s:sequence
@@ -19,6 +19,19 @@ func CheckDefSuccess(lines)
   endtry
 endfunc
 
+" Check that "lines" inside a ":def" function has no error when compiled.
+func CheckDefCompileSuccess(lines)
+  let fname = 'XdefSuccess' .. s:sequence
+  let s:sequence += 1
+  call writefile(['def Func()'] + a:lines + ['enddef', 'defcompile'], fname)
+  try
+    exe 'so ' .. fname
+  finally
+    call delete(fname)
+    delfunc! Func
+  endtry
+endfunc
+
 " Check that "lines" inside ":def" results in an "error" message.
 " If "lnum" is given check that the error is reported for this line.
 " Add a line before and after to make it less likely that the line number is
index 3ce7063d4d4dc161c1d02653495e1efd0eab6eac..7a1fd69ed00f7b34ec6e188f11163596af437331 100644 (file)
@@ -749,6 +749,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3872,
 /**/
     3871,
 /**/