[vim/vim] Vim9: script-local variable can shadow funcref (#7897)

15 views
Skip to first unread message

lacygoill

unread,
Feb 24, 2021, 11:03:28 PM2/24/21
to vim/vim, Subscribed

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

  • Vim version: 8.2 Included patches: 1-2549
  • OS: Ubuntu 16.04.7 LTS
  • Terminal: xterm(366)

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.

lacygoill

unread,
Feb 24, 2021, 11:04:38 PM2/24/21
to vim/vim, Subscribed

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.

lacygoill

unread,
Feb 25, 2021, 12:40:23 AM2/25/21
to vim/vim, Subscribed

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.

lacygoill

unread,
Feb 25, 2021, 12:44:16 AM2/25/21
to vim/vim, Subscribed

: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 = 1
var l = [1, 2, 3]
l->filter(Func)
echo l
[1, 2, 3]

Bram Moolenaar

unread,
Mar 4, 2021, 6:39:08 AM3/4/21
to vim/vim, Subscribed

Closed #7897 via 6c3843c.

Reply all
Reply to author
Forward
0 new messages