Describe the bug
In Vim9 script, a script-local variable can shadow a funcref.
To Reproduce
Run this shell command:
vim -Nu NONE -S <(cat <<'EOF'
vim9script
def Func(i: number, v: number): number
return v * 2
enddef
var Func = 0
var l = [1, 2, 3]
l->map(Func)
echo l
EOF
)
No error is raised. [0, 0, 0] is echo'ed.
Expected behavior
An error is raised, because shadowing is disallowed in Vim9 script:
Variables and functions cannot shadow previously defined or imported variables
and functions.
[2, 4, 6] is echo'ed.
Environment
Additional context
If we allow a variable to shadow a funcref, it could lead to subtle issues which are hard to debug.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.![]()
An error is raised
To be more accurate, this line should raise an error:
var Func = 0
Because there is already a function with the name Func. The user should be forced to choose a different name for their variable.
Actually, I wonder whether the true issue here is that map() doesn't complain when we pass it a number as a second argument. :h map() suggests that it should be a string of a funcref; not a number.
But even if map() is fixed to check that the type of its second argument is valid, I think it should still be an error to use a variable name which has already been used as a function name.
:h map()suggests that it should be a string of a funcref; not a number.
I guess that it doesn't raise any error in Vim script legacy, because the number is automatically coerced into a string. But Vim9 tries to avoid this kind of automatic coercion because they can give unexpected results.
Also, the same issue seems to affect any function accepting a funcref as argument; like filter():
vim9script def Func(i: number, v: number): number
return v % 2 == 0
enddef
var Func = 1var l = [1, 2, 3]
l->filter(Func) echo l
[1, 2, 3]