[vim/vim] Vim9: wrong error while compiling function in debug mode (Issue #9589)

21 views
Skip to first unread message

lacygoill

unread,
Jan 21, 2022, 5:29:26 PM1/21/22
to vim/vim, Subscribed

Steps to reproduce

Run this shell command:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script

    def Callback()
    enddef
    timer_start(0, (_) => Callback())

    breakadd func Func
    autocmd VimEnter * Func()
    def Func()
        eval [][0]
        try
        catch
            return
        endtry
    enddef
EOF
)

Execute the >next debugging command to step over eval [][0].

E684 and E1096 are given:

E684: list index out of range: 0
E1096: Returning a value in a function without a return type

Expected behavior

Only E684 is given. Not E1096; because Func() does not return a value. That is, no argument is passed to the :return command which Func() executes.

Version of Vim

8.2 Included patches: 1-4174

Environment

Operating system: Ubuntu 20.04.3 LTS
Terminal: xterm
Value of $TERM: xterm-256color
Shell: zsh 5.8

Logs and stack traces

N/A


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9589@github.com>

lacygoill

unread,
Jan 21, 2022, 5:31:59 PM1/21/22
to vim/vim, Subscribed

I wrongly assumed that the try/catch block was necessary to reproduce. It's not:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script

    def Callback()
    enddef
    timer_start(0, (_) => Callback())

    breakadd func Func
    autocmd VimEnter * Func()
    def Func()
        eval [][0]
        return
    enddef
EOF
)


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9589/1018912042@github.com>

lacygoill

unread,
Jan 21, 2022, 5:40:47 PM1/21/22
to vim/vim, Subscribed

It seems that the error is not given for Func() but for the timer's callback:

>fu <lambda>1
   def <lambda>1(_: any)
1  return Callback()
   enddef

The definition indeed looks wrong, because there is no return type on the function's header:

def <lambda>1(_: any)

Maybe any should be specified:

def <lambda>1(_: any): any
                       ^^^

I still don't understand why an error is given, because timers should be disabled in debug mode since the patch 8.2.4035.

Also, why does Vim give an error only in debug mode? Why not always?


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9589/1018916286@github.com>

lacygoill

unread,
Jan 21, 2022, 7:55:01 PM1/21/22
to vim/vim, Subscribed

Here is another way to reproduce, which doesn't require a VimEnter autocmd:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script
    cnoremap <expr> <C-U> Func()
    def Func(): string
        Lambda = () => Callback()
        return ''
    enddef
    var Lambda: func
    def Callback()
    enddef
    feedkeys(":debug edit /tmp/file\<CR>", 'ntx')
EOF
)

While on the debug command-line, press <C-U>. E1096 is given:

E1096: Returning a value in a function without a return type

Regression introduced in patch 8.2.4138.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9589/1018997314@github.com>

lacygoill

unread,
Jan 21, 2022, 8:08:30 PM1/21/22
to vim/vim, Subscribed

The definition indeed looks wrong, because there is no return type on the function's header:

[...]


Also, why does Vim give an error only in debug mode? Why not always?

The issue is that since 8.2.4138, the way Vim defines a lambda is wrong when its expression is a function call which does not have a return type.

vim9script
def Callback()
enddef
var Lambda = () => Callback()
execute Lambda
    ->string()
    ->substitute("[()']", ' ', 'g')
   def <lambda>1()
1  return Callback()
   enddef

Notice that the lambda returns a value, but Vim does not specify a return type on the header. That's wrong since 8.2.4138. Since Callback() has no return type, Vim should simply remove the :return statement. That is, it should define the lambda like this:

   def <lambda>1()
1  Callback()
   enddef

I still wonder why an error is only given in debug mode...


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9589/1019001149@github.com>

Bram Moolenaar

unread,
Jan 22, 2022, 7:15:22 AM1/22/22
to vim/vim, Subscribed

The error is only in debug mode, because then the function is compiled twice.
The first time the return type is "unknown", which is handled in the code to set the return type and not give an error.
The second time the return type has already been set to "void" and then "return expr" results in an error.

Let's recognize this is a lambda and not complain about the return type.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9589/1019224584@github.com>

Bram Moolenaar

unread,
Jan 22, 2022, 7:27:49 AM1/22/22
to vim/vim, Subscribed

Closed #9589 via 0bfa849.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issue/9589/issue_event/5936774096@github.com>

Reply all
Reply to author
Forward
0 new messages