patch 9.0.2164: Vim9: can use type a func arg/return value

Problem:  Vim9: can use type a func arg/return value
Solution: Check if using type as function argument or return value

closes: #13675

Signed-off-by: Ernie Rael <errael@raelity.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 38504f1..d582000 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -3197,7 +3197,7 @@
       assert_fails('IntArg(j)', 'E1013: Argument 1: type mismatch, expected number but got job')
       assert_fails('IntArg(ch)', 'E1013: Argument 1: type mismatch, expected number but got channel')
     endif
-    assert_fails('IntArg(A)', 'E1013: Argument 1: type mismatch, expected number but got class<A>')
+    assert_fails('IntArg(A)', 'E1405: Class "A" cannot be used as a value')
     assert_fails('IntArg(o)', 'E1013: Argument 1: type mismatch, expected number but got object<A>')
 
     # Passing a number to functions accepting different argument types
@@ -3262,7 +3262,7 @@
     v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got channel', 2)
   endif
   lines = pre_lines + ['IntArg(A)'] + post_lines
-  v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got class<A>', 1)
+  v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 1)
   lines = pre_lines + ['var o: A = A.new()', 'IntArg(o)'] + post_lines
   v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got object<A>', 2)
 enddef
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 5a9b0f8..6f9723d 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -4149,7 +4149,7 @@
 
     Lock2(C)
   END
-  v9.CheckSourceSuccess(lines)
+  v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
 
   # Lock an object.
   lines =<< trim END
diff --git a/src/testdir/test_vim9_typealias.vim b/src/testdir/test_vim9_typealias.vim
index 11aa47a..8843cb5 100644
--- a/src/testdir/test_vim9_typealias.vim
+++ b/src/testdir/test_vim9_typealias.vim
@@ -546,4 +546,238 @@
   v9.CheckScriptSuccess(lines)
 enddef
 
+" Test for typealias as function arg and return value
+def Test_type_as_func_argument_or_return_value()
+  # check typealias as arg, function call in script level
+  var lines =<< trim END
+    vim9script
+    type A = number
+    def Foo(arg: any)
+    enddef
+    Foo(A)
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "A" cannot be used as a value', 5)
+
+  # check typealias as function return, function call in script level
+  lines =<< trim END
+    vim9script
+    type A = number
+    def Foo(): any
+      return A
+    enddef
+    Foo()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value', 1)
+
+  # check typealias as arg, function call in :def
+  lines =<< trim END
+    vim9script
+    type A = number
+    def Foo(arg: any)
+    enddef
+    def F()
+      Foo(A)
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value', 1)
+
+  # check typealias as function return, function call in :def
+  lines =<< trim END
+    vim9script
+    type A = number
+    def Foo(): any
+      return A
+    enddef
+    def F()
+      Foo()
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value', 1)
+
+  # check funcref using typealias as arg at script level
+  lines =<< trim END
+    vim9script
+    type A = number
+    def F(arg: any)
+      echo typename(arg)
+    enddef
+    var Fref: func(any)
+    Fref = F
+
+    Fref(A)
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "A" cannot be used as a value', 9)
+
+  # check funcref using typealias as arg in :def
+  lines =<< trim END
+    vim9script
+    type A = number
+    def F(arg: any)
+      echo typename(arg)
+    enddef
+    var Fref: func(any)
+    Fref = F
+
+    def G()
+      Fref(A)
+    enddef
+    G()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value', 1)
+
+  # check funcref using typealias as return
+  lines =<< trim END
+    vim9script
+    type A = number
+    def F(): any
+      return A
+    enddef
+    var Fref: func(): any
+    Fref = F
+
+    Fref()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value', 1)
+
+  # check defered function using typealias as arg
+  lines =<< trim END
+    vim9script
+    type A = number
+    def F(arg: any)
+    enddef
+    def G()
+      defer F(A)
+    enddef
+    G()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value', 1)
+enddef
+
+" Test for class typealias as function arg and return value
+def Test_class_as_func_argument_or_return_value()
+  # check class typealias as arg, function call in script level
+  var lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def Foo(arg: any)
+    enddef
+    Foo(A)
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 7)
+
+  # check class typealias as function return, function call in script level
+  lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def Foo(): any
+      return A
+    enddef
+    Foo()
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 1)
+
+  # check class typealias as arg, function call in :def
+  lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def Foo(arg: any)
+    enddef
+    def F()
+      Foo(A)
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 1)
+
+  # check class typealias as function return, function call in :def
+  lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def Foo(): any
+      return A
+    enddef
+    def F()
+      Foo()
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 1)
+
+  # check funcref using class typealias as arg at script level
+  lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def F(arg: any)
+      echo typename(arg)
+    enddef
+    var Fref: func(any)
+    Fref = F
+
+    Fref(A)
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 11)
+
+  # check funcref using class typealias as arg in :def
+  lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def F(arg: any)
+      echo typename(arg)
+    enddef
+    var Fref: func(any)
+    Fref = F
+
+    def G()
+      Fref(A)
+    enddef
+    G()
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 1)
+
+  # check funcref using class typealias as return
+  lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def F(): any
+      return A
+    enddef
+    var Fref: func(): any
+    Fref = F
+
+    Fref()
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 1)
+
+  # check defered function using class typealias as arg
+  lines =<< trim END
+    vim9script
+    class C
+    endclass
+    type A = C
+    def F(arg: any)
+    enddef
+    def G()
+      defer F(A)
+    enddef
+    G()
+  END
+  v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 1)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker