[vim/vim] Vim9: no error for shadowing exported autoload function (Issue #9577)

4 views
Skip to first unread message

lacygoill

unread,
Jan 20, 2022, 12:20:32 PM1/20/22
to vim/vim, Subscribed

Steps to reproduce

Run this shell command:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script
    var dir = '/tmp/.vim'
    &runtimepath = dir
    dir ..= '/autoload'
    dir->mkdir('p')
    var lines =<< trim END
        vim9script
        def script#()
        enddef
        export def Func()
            echo 'this Func() is shadowed'
        enddef
        def Func()
            echo 'this Func() shadows the exported Func()'
        enddef
        Func()
    END
    lines->writefile(dir .. '/script.vim')
    script#()
EOF
)

No error is given. This is echo'ed:

this Func() shadows the exported Func()

Expected behavior

An error is given:

E1073: Name already defined: <SNR>2_Func

Nothing is echo'ed.

Version of Vim

8.2 Included patches: 1-4160

Environment

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

Additional context

If we remove the second non-exported Func(), then we can again access the exported Func() without using the script#Func() notation:

vim9script
var dir = '/tmp/.vim'
&runtimepath = dir
dir ..= '/autoload'
dir->mkdir('p')
var lines =<< trim END
    vim9script
    def script#()
    enddef
    export def Func()
        echo 'this Func() is no longer shadowed'
    enddef
    Func()
END
lines->writefile(dir .. '/script.vim')
script#()
this Func() is no longer shadowed

This confirms that in the original snippet, there was indeed a shadowing.


In an import script, the same shadowing is disallowed:

vim9script
var dir = '/tmp/.vim'
&runtimepath = dir
dir ..= '/import'
dir->mkdir('p')
var lines =<< trim END
    vim9script
    export def Func()
    enddef
    def Func()
    enddef
END
lines->writefile(dir .. '/script.vim')
import 'script.vim'
E1073: Name already defined: <SNR>2_Func

This is good, and it should be disallowed in an autoload script too; otherwise, it can cause confusing issues.


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/9577@github.com>

Bram Moolenaar

unread,
Jan 20, 2022, 2:11:16 PM1/20/22
to vim/vim, Subscribed

Closed #9577 via 9c7cae6.


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/9577/issue_event/5927461533@github.com>

Dominique Pellé

unread,
Jan 20, 2022, 7:16:01 PM1/20/22
to vim/vim, Subscribed

The fix for this issue broke my vim config.
See my earlier post in vim_dev for more details at:
https://www.mail-archive.com/vim...@googlegroups.com/msg61596.html


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/9577/1018040355@github.com>

lacygoill

unread,
Jan 20, 2022, 7:27:22 PM1/20/22
to vim/vim, Subscribed

That's what I feared. Some plugins call path#to#autoload#script#(), like vim-plug. Not sure if other plugins do that too, or if it's the only one. Anyway, if we don't want to break existing legacy scripts, we might want to limit the check for an autoload function name to Vim9 script, and still allow unnamed functions in legacy scripts.


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/9577/1018046042@github.com>

lacygoill

unread,
Jan 20, 2022, 7:40:33 PM1/20/22
to vim/vim, Subscribed

For anyone having the same issue, try to apply the patch given here for a temporary fix. This is meant to be applied on the autoload/plug.vim script.


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/9577/1018052876@github.com>

lacygoill

unread,
Jan 21, 2022, 2:24:25 PM1/21/22
to vim/vim, Subscribed

While we're on the subject of weird things that are allowed in legacy, we can use the script# prefix to name a function even if it's in a plugin/ directory:

vim -Nu <(tee <<'EOF'
    vim9script
    var dir = '/tmp/.vim'
    &runtimepath = dir
    dir ..= '/plugin'
    dir->mkdir('p')
    var lines =<< trim END
        vim9script
        def script#func()
            echomsg 'from script#func() which is not autoloaded'
        enddef
    END
    lines->writefile(dir .. '/script.vim')
    autocmd VimEnter * script#func()
EOF
)

This echo'es:

from script#func() which is not autoloaded

It seems weird because the path#to#script# prefix is meant to be used for autoloaded functions. But here, script#func() is not autoloaded. It's under a plugin/ directory of the runtimepath. IOW, it's immediately sourced on startup.

Not sure, but maybe that should be disallowed in Vim9. However, it must remain allowed in legacy, because several existing plugins rely on it.


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/9577/1018794161@github.com>

Bram Moolenaar

unread,
Jan 21, 2022, 3:38:17 PM1/21/22
to vim/vim, Subscribed


> While we're on the subject of weird things that are allowed in legacy,
> we can use the `script#` prefix to name a function even if it's in a
> `plugin/` directory:
>
> vim -Nu <(tee <<'EOF'

> vim9script
> var dir = '/tmp/.vim'
> &runtimepath = dir
> dir ..= '/plugin'

> dir->mkdir('p')
> var lines =<< trim END
> vim9script
> def script#func()
> echomsg 'from script#func() which is not autoloaded'
> enddef
> END
> lines->writefile(dir .. '/script.vim')
> autocmd VimEnter * script#func()
> EOF
> )
>
> This echo'es:
>
> from script#func() which is not autoloaded
>
> It seems weird because the `path#to#script#` prefix is meant to be
> used for autoloaded functions. But here, `script#func()` is not
> autoloaded. It's under a `plugin/` directory of the runtimepath.
> IOW, it's immediately sourced on startup.
>
> Not sure, but maybe that should be disallowed in Vim9. However, it
> must remain allowed in legacy, because several existing plugins rely
> on it.

I agree, we should not allow using an autoload name in a non-autoload
script, it can cause a lot of confusion.

--
TIM: That is not an ordinary rabbit ... 'tis the most foul cruel and
bad-tempered thing you ever set eyes on.
ROBIN: You tit. I soiled my armour I was so scared!
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

/// Bram Moolenaar -- ***@***.*** -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///


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/9577/1018841878@github.com>

Reply all
Reply to author
Forward
0 new messages