Mercurial > vim
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