diff src/testdir/test_vim9_typealias.vim @ 33949:84b93d95a952 v9.0.2169

patch 9.0.2169: Vim9: builtin funcs may accept a non-value Commit: https://github.com/vim/vim/commit/d8bf87c9fbd92fd6b837446e886d47e557adadbc Author: Ernie Rael <errael@raelity.com> Date: Sat Dec 16 14:03:33 2023 +0100 patch 9.0.2169: Vim9: builtin funcs may accept a non-value Problem: Vim9: builtin funcs may accept a non-value Solution: Restrict builtin functions that accept `type` This PR finishes off detection and prevention of using a type as a value. It takes care of builtin functions. However there are some builtin functions, that need to be able to handle types as well as non-args: instanceof(), type(), typename(), string(). A "bit", FE_X, is added to funcentry_T; when set, the builtin function can handle a type (class or type-alias) in addition to a value. Noteworthy change: Discovered that in compile_call() the builtin add() is compiled inline instead of calling the builtin. Had to add a check there. closes: #13688 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Sat, 16 Dec 2023 14:15:03 +0100
parents 3bba09502b8d
children ab6a70fad5b5
line wrap: on
line diff
--- a/src/testdir/test_vim9_typealias.vim
+++ b/src/testdir/test_vim9_typealias.vim
@@ -296,7 +296,7 @@ def Test_typealias()
     type A = list<string>
     var x = json_encode(A)
   END
-  v9.CheckSourceFailure(lines, 'E1161: Cannot json encode a typealias', 3)
+  v9.CheckSourceFailure(lines, 'E1403: Type alias "A" cannot be used as a value', 3)
 
   # Comparing type alias with a number (script level)
   lines =<< trim END
@@ -452,9 +452,9 @@ def Test_typealias_with_builtin_function
   var lines =<< trim END
     vim9script
     type A = list<func>
-    assert_equal(0, empty(A))
+    var x = empty(A)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "A" cannot be used as a value', 3)
 
   # Using a type alias with len()
   lines =<< trim END
@@ -462,7 +462,7 @@ def Test_typealias_with_builtin_function
     type A = list<func>
     var x = len(A)
   END
-  v9.CheckScriptFailure(lines, 'E701: Invalid type for len()', 3)
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "A" cannot be used as a value', 3)
 
   # Using a type alias with len()
   lines =<< trim END
@@ -473,7 +473,7 @@ def Test_typealias_with_builtin_function
     enddef
     Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<any> but got typealias', 1)
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value', 1)
 
   # Using a type alias with eval()
   lines =<< trim END
@@ -780,4 +780,134 @@ def Test_class_as_func_argument_or_retur
   v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value', 1)
 enddef
 
+def Test_passing_typealias_to_builtin()
+  # type, typename, string, instanceof are allowed type argument
+  var lines =<< trim END
+    vim9script
+    type T = number
+    var x: any
+    x = type(T)
+    x = typename(T)
+    x = string(T)
+  END
+  v9.CheckScriptSuccess(lines)
+
+  # check argument to add at script level
+  # Note: add() is special cased in compile_call in vim9expr
+  lines =<< trim END
+    vim9script
+    type T = number
+    add([], T)
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "T" cannot be used as a value')
+
+  # check argument to add in :def
+  lines =<< trim END
+    vim9script
+    type T = number
+    def F()
+      add([], T)
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value')
+
+  # check member call argument to add at script level
+  lines =<< trim END
+    vim9script
+    type T = number
+    []->add(T)
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "T" cannot be used as a value')
+
+  # check member call argument to add in :def
+  lines =<< trim END
+    vim9script
+    type T = number
+    def F()
+      []->add(T)
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value')
+
+  # Try "empty()" builtin
+  # check argument to empty at script level
+  lines =<< trim END
+    vim9script
+    type T = number
+    empty(T)
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "T" cannot be used as a value')
+
+  # check argument to empty in :def
+  lines =<< trim END
+    vim9script
+    type T = number
+    def F()
+      empty(T)
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value')
+
+  # check member call argument to empty at script level
+  lines =<< trim END
+    vim9script
+    type T = number
+    T->empty()
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "T" cannot be used as a value')
+
+  # check member call argument to empty in :def
+  lines =<< trim END
+    vim9script
+    type T = number
+    def F()
+      T->empty()
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value')
+
+  # Try "abs()" builtin
+  # check argument to abs at script level
+  lines =<< trim END
+    vim9script
+    type T = number
+    abs(T)
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "T" cannot be used as a value')
+
+  # check argument to abs in :def
+  lines =<< trim END
+    vim9script
+    type T = number
+    def F()
+      abs(T)
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value')
+
+  # check member call argument to abs at script level
+  lines =<< trim END
+    vim9script
+    type T = number
+    T->abs()
+  END
+  v9.CheckScriptFailure(lines, 'E1403: Type alias "T" cannot be used as a value')
+
+  # check member call argument to abs in :def
+  lines =<< trim END
+    vim9script
+    type T = number
+    def F()
+      T->abs()
+    enddef
+    F()
+  END
+  v9.CheckScriptFailure(lines, 'E1407: Cannot use a Typealias as a variable or value')
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker