[vim/vim] Vim9: inconsistent type checking when passing output of funcref to "get()" (#8644)

6 views
Skip to first unread message

lacygoill

unread,
Jul 26, 2021, 11:11:40 AM7/26/21
to vim/vim, Subscribed

Describe the bug

In Vim9 script, passing the output of a funcref to get() might give an error in compiled code, but not at the script level, which is inconsistent.

To Reproduce

Run this shell command:

vim -Nu NONE -S <(cat <<'EOF'
    vim9script
    var Getqflist: func = function('getqflist', [{id: 0}])
    Getqflist()->get('id', 0)
EOF
)

No error is given.

Now, run the same code in a :def function:

vim -Nu NONE -S <(cat <<'EOF'
    vim9script
    def Func(): number
        var Getqflist: func = function('getqflist', [{id: 0}])
        return Getqflist()->get('id', 0)
    enddef
    defcompile
EOF
)

E1013 is given:

E1013: Argument 1: type mismatch, expected list<any> but got unknown

Expected behavior

I think the second command should not give an error, to be consistent with what happens at the script level.

IOW, if Vim doesn't know what the output of a function is, it should be treated as any. Does that make sense? Or would this lead to other issues?

Environment

  • Vim version: 8.2 Included patches: 1-3223
  • OS: Ubuntu 20.04.2 LTS
  • Terminal: XTerm(353)

Additional context

As a workaround, we can declare the return type of the funcref with list<any>:

var Getqflist: func: list<any> = function('getqflist', [{id: 0}])
                     ^-------^

Test:

vim9script
def Func(): number
    var Getqflist: func: list<any> = function('getqflist', [{id: 0}])
    return Getqflist()->get('id', 0)
enddef
defcompile
echo 'no error'
no error

If it is a regression, then it was introduced in 8.2.3221.

cc @yegappan via #8632


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

Yegappan Lakshmanan

unread,
Jul 26, 2021, 11:48:46 AM7/26/21
to vim_dev, reply+ACY5DGEE64D3TKANOF...@reply.github.com, vim/vim, Subscribed
Hi,

The argument type check for the get() function already accepts the "any" type
for the first argument. But in this case, the type is "unknown". To support this,
we need to disable the type check for the first argument of get().

- Yegappan

vim-dev ML

unread,
Jul 26, 2021, 11:49:05 AM7/26/21
to vim/vim, vim-dev ML, Your activity

Hi,

On Mon, Jul 26, 2021 at 8:11 AM lacygoill ***@***.***> wrote:

> *Describe the bug*

>
> In Vim9 script, passing the output of a funcref to get() might give an
> error in compiled code, but not at the script level, which is inconsistent.
>
> *To Reproduce*

>
> Run this shell command:
>
> vim -Nu NONE -S <(cat <<'EOF'
> vim9script
> var Getqflist: func = function('getqflist', [{id: 0}])
> Getqflist()->get('id', 0)
> EOF
> )
>
> No error is given.
>
> Now, run the same code in a :def function:
>
> vim -Nu NONE -S <(cat <<'EOF'
> vim9script
> def Func(): number
> var Getqflist: func = function('getqflist', [{id: 0}])
> return Getqflist()->get('id', 0)
> enddef
> defcompile
> EOF
> )
>
> E1013 is given:
>
> E1013: Argument 1: type mismatch, expected list<any> but got unknown
>
> *Expected behavior*

>
> I think the second command should not give an error, to be consistent with
> what happens at the script level.
>
> IOW, if Vim doesn't know what the output of a function is, it should be
> treated as any. Does that make sense? Or would this lead to other issues?
>

The argument type check for the get() function already accepts the "any"
type
for the first argument. But in this case, the type is "unknown". To support
this,
we need to disable the type check for the first argument of get().

- Yegappan


> *Environment*
>
> - Vim version: 8.2 Included patches: 1-3223
> - OS: Ubuntu 20.04.2 LTS
> - Terminal: XTerm(353)
>
> *Additional context*

>
> As a workaround, we can declare the return type of the funcref with
> list<any>:
>
> var Getqflist: func: list<any> = function('getqflist', [{id: 0}])
> ^-------^
>
> Test:
>
> vim9scriptdef Func(): number

> var Getqflist: func: list<any> = function('getqflist', [{id: 0}])
> return Getqflist()->get('id', 0)enddefdefcompileecho 'no error'
>
> no error
>
> ------------------------------
>
> *If* it is a regression, then it was introduced in 8.2.3221
> <https://github.com/vim/vim/releases/tag/v8.2.3221>.
>
> cc @yegappan <https://github.com/yegappan> via #8632
> <https://github.com/vim/vim/pull/8632>

lacygoill

unread,
Jul 26, 2021, 11:54:55 AM7/26/21
to vim/vim, vim-dev ML, Comment

Closed #8644.


You are receiving this because you commented.

lacygoill

unread,
Jul 26, 2021, 11:54:56 AM7/26/21
to vim/vim, vim-dev ML, Comment

To support this, we need to disable the type check for the first argument of get().

Since we can pass the output of such a funcref to any other function, that would mean disable type checking entirely, which is not possible. So, closing the issue.


You are receiving this because you commented.

lacygoill

unread,
Jul 26, 2021, 12:00:02 PM7/26/21
to vim/vim, vim-dev ML, Comment

I re-open because maybe Vim should not infer the return type as unknown; maybe it should be any.

Also, this comment might be relevant (in particular the end "may also have caused some bugs"):

Note that I recently made :def functions return void
instead of zero, and for lambda make the return type unknown until it is
compiled. These changes have improved some things, but may also have
caused some bugs.

Source.

Feel free to close the issue, if it can't be fixed. We certainly don't want to disable type checking entirely for get(), nor for any other builtin function.


You are receiving this because you commented.

lacygoill

unread,
Jul 26, 2021, 12:00:03 PM7/26/21
to vim/vim, vim-dev ML, Comment

Reopened #8644.


You are receiving this because you commented.

Bram Moolenaar

unread,
Jul 27, 2021, 4:22:11 PM7/27/21
to vim/vim, vim-dev ML, Comment

Closed #8644 via f723701.


You are receiving this because you commented.

Reply all
Reply to author
Forward
0 new messages