changeset 20207:3c247d9cd6f9 v8.2.0659

patch 8.2.0659: Vim9: no test for equal func type Commit: https://github.com/vim/vim/commit/939b5db4808770d3a2ec35e3902a9d5165adc0cf Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 28 22:49:08 2020 +0200 patch 8.2.0659: Vim9: no test for equal func type Problem: Vim9: no test for equal func type. Solution: Add a test. Improve type check.
author Bram Moolenaar <Bram@vim.org>
date Tue, 28 Apr 2020 23:00:04 +0200
parents b7046165cf39
children 061dfda170cd
files src/testdir/test_vim9_expr.vim src/version.c src/vim9compile.c
diffstat 3 files changed, 21 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -30,6 +30,16 @@ def Test_expr1()
   assert_equal('two', {} ? 'one' : 'two')
   var = 0
   assert_equal('two', var ? 'one' : 'two')
+
+  let Some: func = function('len')
+  let Other: func = function('winnr')
+  let Res: func = g:atrue ? Some : Other
+  assert_equal(function('len'), Res)
+
+  let RetOne: func(string): number = function('len')
+  let RetTwo: func(string): number = function('winnr')
+  let RetThat: func = g:atrue ? RetOne : RetTwo
+  assert_equal(function('len'), RetThat)
 enddef
 
 func Test_expr1_fails()
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    659,
+/**/
     658,
 /**/
     657,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -724,7 +724,8 @@ generate_TYPECHECK(cctx_T *cctx, type_T 
     RETURN_OK_IF_SKIP(cctx);
     if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL)
 	return FAIL;
-    isn->isn_arg.type.ct_type = vartype->tt_type;  // TODO: whole type
+    // TODO: whole type, e.g. for a function also arg and return types
+    isn->isn_arg.type.ct_type = vartype->tt_type;
     isn->isn_arg.type.ct_off = offset;
 
     // type becomes vartype
@@ -2594,6 +2595,7 @@ arg_type_mismatch(type_T *expected, type
 
 /*
  * Check if the expected and actual types match.
+ * Does not allow for assigning "any" to a specific type.
  */
     static int
 check_type(type_T *expected, type_T *actual, int give_msg)
@@ -2603,7 +2605,8 @@ check_type(type_T *expected, type_T *act
     // When expected is "unknown" we accept any actual type.
     // When expected is "any" we accept any actual type except "void".
     if (expected->tt_type != VAR_UNKNOWN
-	    && (expected->tt_type != VAR_ANY || actual->tt_type == VAR_VOID))
+	    && !(expected->tt_type == VAR_ANY && actual->tt_type != VAR_VOID))
+
     {
 	if (expected->tt_type != actual->tt_type)
 	{
@@ -2643,7 +2646,10 @@ need_type(type_T *actual, type_T *expect
 {
     if (check_type(expected, actual, FALSE) == OK)
 	return OK;
-    if (actual->tt_type != VAR_ANY && actual->tt_type != VAR_UNKNOWN)
+    if (actual->tt_type != VAR_ANY
+	    && actual->tt_type != VAR_UNKNOWN
+	    && !(actual->tt_type == VAR_FUNC
+		&& (actual->tt_member == &t_any || actual->tt_argcount < 0)))
     {
 	type_mismatch(expected, actual);
 	return FAIL;