Describe the bug
In Vim9 script, we cannot use a number to test the existence of a number key from a dictionary with has_key().
To Reproduce
Run this shell command:
vim -Nu NONE -S <(cat <<'EOF'
vim9script
def Func()
var d = {123: 'value'}
var n = 123
echo d->has_key(n)
enddef
defcompile
EOF
)
E1013 is raised:
E1013: Argument 2: type mismatch, expected string but got number
Expected behavior
No error is raised.
Environment
Additional context
The exact same code doesn't give any error at the script level:
vim9script var d = {123: 'value'} var n = 123 echo d->has_key(n)
1
Which is inconsistent.
Regression introduced in 8.2.3135.
One might argue that the error is expected because keys in a dictionary are strings, not numbers, hence why has_key() expects a string as its second argument.
True, but it's also:
string()Regarding the 2nd bullet point:
vim9script var d = {123: 'value'} var n = 123 echo d[n]
value
Notice that Vim didn't complain; it automatically coerced the value of the n number variable (123) into a string ('123').
This is inconsistent. We don't need to manually coerce a number key to get its value with the [n] notation, but we do need to coerce it to test its existence with has_key().
I understand that type checking is important, but I think it should be enforced only when it helps. And I don't think it will help here to find and fix bugs. I think it's just annoying. I'm not alone:
I do think that using a number or bool as the key is very useful, and requiring string() is not helping.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.![]()
It would certainly be more efficient to store the keys in the dictionary as numbers when numbers are required. Though, I don't know if that's possible with the current implementation.
I encountered the same issue when I used a dictionary as a replacement for a set to store unique numbers.
Something else is still broken by the same patch:
vim9script def Func() virtcol([1, 1]) enddef defcompile
E1013: Argument 1: type mismatch, expected list<string> but got list<number>
There should be no error. It worked before, and while this code is useless, it's a simplification of a code which is useful.
Also, it's inconsistent for 2 reasons:
vim9script virtcol([1, 1])
No error at the script level, but error in compiled code.
vim9script def Func() virtcol([1, '$']) enddef defcompile
No error in compiled code if one of the items is the string '$'. This means that Vim is ok with list<any>. But the previous error said that Vim expected list<string>.
To be consistent, Vim should accept list<any> at the script level and in compiled code.
To be consistent, Vim should accept list at the script level and in compiled code.
And it should accept list<number>.
Something else is still broken by the same patch:
vim9script def Func() virtcol([1, 1]) enddef defcompileE1013: Argument 1: type mismatch, expected list<string> but got list<number>There should be no error. It worked before, and while this code is useless, it's a simplification of a code which is useful.