GNU bug report logs - #69290
declare-function doesn't work when combined with --eval and -batch

Previous Next

Package: emacs;

Reported by: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>

Date: Tue, 20 Feb 2024 19:01:01 UTC

Severity: normal

To reply to this bug, email your comments to 69290 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 19:01:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Konstantin Kharlamov <Hi-Angel <at> yandex.ru>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 20 Feb 2024 19:01:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
To: bug-gnu-emacs <at> gnu.org
Subject: declare-function doesn't work when combined with --eval and -batch
Date: Tue, 20 Feb 2024 21:59:31 +0300
Stumbled upon that while trying to improve CI in Evil mode. Enabling byte-compilation
causes warnings about `undo-redo` undeclared on older Emacs'es, so tried to work
around that with `declare-function`. Turns out it doesn't work.


# Steps to reproduce (in terms of terminal commands)

    λ cat test.el
    ;;; -*- lexical-binding: t -*-
    (hello)
    λ emacs -batch --eval '(declare-function hello nil)' -f batch-byte-compile test.el

    In end of data:
    test.el:2:2: Warning: the function ‘hello’ is not known to be defined.

## Expected

There's no warning

## Actual

There's a warning about undeclared function which is declared

# Additional information

Versions tested:

* commit d4d5830f8a0 built 3 weeks ago from master.
* 27.1, 26.3, 25.3




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 19:53:01 GMT) Full text and rfc822 format available.

Message #8 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with --eval
 and -batch
Date: Tue, 20 Feb 2024 21:51:59 +0200
> From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> Date: Tue, 20 Feb 2024 21:59:31 +0300
> 
> Stumbled upon that while trying to improve CI in Evil mode. Enabling byte-compilation
> causes warnings about `undo-redo` undeclared on older Emacs'es, so tried to work
> around that with `declare-function`. Turns out it doesn't work.

Of course it does.  If used correctly, that is.  We do that in
gazillion places in our sources.

>     λ cat test.el
>     ;;; -*- lexical-binding: t -*-
>     (hello)
>     λ emacs -batch --eval '(declare-function hello nil)' -f batch-byte-compile test.el
> 
>     In end of data:
>     test.el:2:2: Warning: the function ‘hello’ is not known to be defined.
> 
> ## Expected
> 
> There's no warning

What does the doc string of declare-function tell you about its usage
and effect?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 19:57:02 GMT) Full text and rfc822 format available.

Message #11 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with
 --eval and -batch
Date: Tue, 20 Feb 2024 22:56:01 +0300
On Tue, 2024-02-20 at 21:51 +0200, Eli Zaretskii wrote:
> > From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> > Date: Tue, 20 Feb 2024 21:59:31 +0300
> > 
> > Stumbled upon that while trying to improve CI in Evil mode.
> > Enabling byte-compilation
> > causes warnings about `undo-redo` undeclared on older Emacs'es, so
> > tried to work
> > around that with `declare-function`. Turns out it doesn't work.
> 
> Of course it does.  If used correctly, that is.  We do that in
> gazillion places in our sources.
> 
> >     λ cat test.el
> >     ;;; -*- lexical-binding: t -*-
> >     (hello)
> >     λ emacs -batch --eval '(declare-function hello nil)' -f batch-
> > byte-compile test.el
> > 
> >     In end of data:
> >     test.el:2:2: Warning: the function ‘hello’ is not known to be
> > defined.
> > 
> > ## Expected
> > 
> > There's no warning
> 
> What does the doc string of declare-function tell you about its usage
> and effect?

It says `Tell the byte-compiler that function FN is defined, in FILE`,
and then FILE may be nil. In the context of the problem it seems the
only thing that's relevant. There's a lot more text, but the rest of it
just explains behavior of different parameters. Is there anything I'm
missing?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 20:05:02 GMT) Full text and rfc822 format available.

Message #14 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with
 --eval and -batch
Date: Tue, 20 Feb 2024 22:03:55 +0200
> From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> Cc: 69290 <at> debbugs.gnu.org
> Date: Tue, 20 Feb 2024 22:56:01 +0300
> 
> On Tue, 2024-02-20 at 21:51 +0200, Eli Zaretskii wrote:
> > >     λ emacs -batch --eval '(declare-function hello nil)' -f batch-
> > > byte-compile test.el
> > > 
> > >     In end of data:
> > >     test.el:2:2: Warning: the function ‘hello’ is not known to be
> > > defined.
> > > 
> > > ## Expected
> > > 
> > > There's no warning
> > 
> > What does the doc string of declare-function tell you about its usage
> > and effect?
> 
> It says `Tell the byte-compiler that function FN is defined, in FILE`,
> and then FILE may be nil. In the context of the problem it seems the
> only thing that's relevant. There's a lot more text, but the rest of it
> just explains behavior of different parameters. Is there anything I'm
> missing?

Does --eval '(declare-function hello nil)' tell anything to the
byte-compiler?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 20:15:01 GMT) Full text and rfc822 format available.

Message #17 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with
 --eval and -batch
Date: Tue, 20 Feb 2024 23:13:27 +0300
On Tue, 2024-02-20 at 22:03 +0200, Eli Zaretskii wrote:
> > From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> > Cc: 69290 <at> debbugs.gnu.org
> > Date: Tue, 20 Feb 2024 22:56:01 +0300
> > 
> > On Tue, 2024-02-20 at 21:51 +0200, Eli Zaretskii wrote:
> > > >     λ emacs -batch --eval '(declare-function hello nil)' -f
> > > > batch-
> > > > byte-compile test.el
> > > > 
> > > >     In end of data:
> > > >     test.el:2:2: Warning: the function ‘hello’ is not known to
> > > > be
> > > > defined.
> > > > 
> > > > ## Expected
> > > > 
> > > > There's no warning
> > > 
> > > What does the doc string of declare-function tell you about its
> > > usage
> > > and effect?
> > 
> > It says `Tell the byte-compiler that function FN is defined, in
> > FILE`,
> > and then FILE may be nil. In the context of the problem it seems
> > the
> > only thing that's relevant. There's a lot more text, but the rest
> > of it
> > just explains behavior of different parameters. Is there anything
> > I'm
> > missing?
> 
> Does --eval '(declare-function hello nil)' tell anything to the
> byte-compiler?

Well, I can guess by the way you're asking that the answer is "no", but
I have no idea why so. It should. It is the same as if you pop up
Emacs, evaluate a (defun hello()) and then call `byte-compile-file`
over the `test.el`. There won't be a warning, despite that `(defun
hello ())` was never byte-compiled (AFAIK Emacs does note byte-compile
evaluated code).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 20:22:02 GMT) Full text and rfc822 format available.

Message #20 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with
 --eval and -batch
Date: Tue, 20 Feb 2024 22:20:24 +0200
> From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> Cc: 69290 <at> debbugs.gnu.org
> Date: Tue, 20 Feb 2024 23:13:27 +0300
> 
> > Does --eval '(declare-function hello nil)' tell anything to the
> > byte-compiler?
> 
> Well, I can guess by the way you're asking that the answer is "no", but
> I have no idea why so. It should.

How can it?  The declare-function form is evaluated by the startup
code, and only after that the byte-compiler is invoked to compile
test.el.  At least this is my analysis of what happens here.

> It is the same as if you pop up Emacs, evaluate a (defun hello())
> and then call `byte-compile-file` over the `test.el`. There won't be
> a warning, despite that `(defun hello ())` was never byte-compiled
> (AFAIK Emacs does note byte-compile evaluated code).

For the declare-function form to take effect, the byte-compiler needs
to evaluate the form.  By contrast, defun is evaluated by the Lisp
interpreter and the result is stored in the global state.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 20:33:01 GMT) Full text and rfc822 format available.

Message #23 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with
 --eval and -batch
Date: Tue, 20 Feb 2024 23:31:53 +0300
On Tue, 2024-02-20 at 22:20 +0200, Eli Zaretskii wrote:
> > From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> > Cc: 69290 <at> debbugs.gnu.org
> > Date: Tue, 20 Feb 2024 23:13:27 +0300
> > 
> > > Does --eval '(declare-function hello nil)' tell anything to the
> > > byte-compiler?
> > 
> > Well, I can guess by the way you're asking that the answer is "no",
> > but
> > I have no idea why so. It should.
> 
> How can it?  The declare-function form is evaluated by the startup
> code, and only after that the byte-compiler is invoked to compile
> test.el.  At least this is my analysis of what happens here.
> 
> > It is the same as if you pop up Emacs, evaluate a (defun hello())
> > and then call `byte-compile-file` over the `test.el`. There won't
> > be
> > a warning, despite that `(defun hello ())` was never byte-compiled
> > (AFAIK Emacs does note byte-compile evaluated code).
> 
> For the declare-function form to take effect, the byte-compiler needs
> to evaluate the form.  By contrast, defun is evaluated by the Lisp
> interpreter and the result is stored in the global state.

Oh, thank you for explanation, I see. It's doesn't seem to be obvious
to a bystander, because from the side it seems like in Emacs byte-
compiler and interpreter should work in a tandem, as in the example
with evaluating (defun hello()). In Emacs context the doc-string that
says `Tell the byte-compiler that function FN is defined` would read to
me as "modify global state, which later will be read by byte-compiler
to deem FN as defined". IOW, to me as a bystander the documentation
string does not explain the difference, which is why we just had this
somewhat long discussion before I understood why `declare-function`
works this way.

I guess the bug can be closed, sorry for the noise.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Tue, 20 Feb 2024 21:30:02 GMT) Full text and rfc822 format available.

Message #26 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with
 --eval and -batch
Date: Wed, 21 Feb 2024 00:28:46 +0300
On Tue, 2024-02-20 at 23:31 +0300, Konstantin Kharlamov wrote:
> On Tue, 2024-02-20 at 22:20 +0200, Eli Zaretskii wrote:
> > > From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> > > Cc: 69290 <at> debbugs.gnu.org
> > > Date: Tue, 20 Feb 2024 23:13:27 +0300
> > > 
> > > > Does --eval '(declare-function hello nil)' tell anything to the
> > > > byte-compiler?
> > > 
> > > Well, I can guess by the way you're asking that the answer is
> > > "no",
> > > but
> > > I have no idea why so. It should.
> > 
> > How can it?  The declare-function form is evaluated by the startup
> > code, and only after that the byte-compiler is invoked to compile
> > test.el.  At least this is my analysis of what happens here.
> > 
> > > It is the same as if you pop up Emacs, evaluate a (defun hello())
> > > and then call `byte-compile-file` over the `test.el`. There won't
> > > be
> > > a warning, despite that `(defun hello ())` was never byte-
> > > compiled
> > > (AFAIK Emacs does note byte-compile evaluated code).
> > 
> > For the declare-function form to take effect, the byte-compiler
> > needs
> > to evaluate the form.  By contrast, defun is evaluated by the Lisp
> > interpreter and the result is stored in the global state.
> 
> Oh, thank you for explanation, I see. It's doesn't seem to be obvious
> to a bystander, because from the side it seems like in Emacs byte-
> compiler and interpreter should work in a tandem, as in the example
> with evaluating (defun hello()). In Emacs context the doc-string that
> says `Tell the byte-compiler that function FN is defined` would read
> to
> me as "modify global state, which later will be read by byte-compiler
> to deem FN as defined". IOW, to me as a bystander the documentation
> string does not explain the difference, which is why we just had this
> somewhat long discussion before I understood why `declare-function`
> works this way.

Btw, I just figured out how to show you why this doc-string doesn't say
anything on the matter. Imagine for a second that `declare-function` is
getting through from "eval" to the byte-compiler, i.e. the problem
we're discussing is just not present. Would you change the string `Tell
the byte-compiler that function FN is defined` to something else in
this case? I would not, because it's still byte-compiler that does all
the checking, so the point that "declare-function" is purposed for
`byte-compiler` stands.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69290; Package emacs. (Wed, 21 Feb 2024 03:31:01 GMT) Full text and rfc822 format available.

Message #29 received at 69290 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 69290 <at> debbugs.gnu.org
Subject: Re: bug#69290: declare-function doesn't work when combined with
 --eval and -batch
Date: Wed, 21 Feb 2024 05:30:22 +0200
> From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> Cc: 69290 <at> debbugs.gnu.org
> Date: Wed, 21 Feb 2024 00:28:46 +0300
> 
> On Tue, 2024-02-20 at 23:31 +0300, Konstantin Kharlamov wrote:
> > On Tue, 2024-02-20 at 22:20 +0200, Eli Zaretskii wrote:
> > > > From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> > > > Cc: 69290 <at> debbugs.gnu.org
> > > > Date: Tue, 20 Feb 2024 23:13:27 +0300
> > > > 
> > > > > Does --eval '(declare-function hello nil)' tell anything to the
> > > > > byte-compiler?
> > > > 
> > > > Well, I can guess by the way you're asking that the answer is
> > > > "no",
> > > > but
> > > > I have no idea why so. It should.
> > > 
> > > How can it?  The declare-function form is evaluated by the startup
> > > code, and only after that the byte-compiler is invoked to compile
> > > test.el.  At least this is my analysis of what happens here.
> > > 
> > > > It is the same as if you pop up Emacs, evaluate a (defun hello())
> > > > and then call `byte-compile-file` over the `test.el`. There won't
> > > > be
> > > > a warning, despite that `(defun hello ())` was never byte-
> > > > compiled
> > > > (AFAIK Emacs does note byte-compile evaluated code).
> > > 
> > > For the declare-function form to take effect, the byte-compiler
> > > needs
> > > to evaluate the form.  By contrast, defun is evaluated by the Lisp
> > > interpreter and the result is stored in the global state.
> > 
> > Oh, thank you for explanation, I see. It's doesn't seem to be obvious
> > to a bystander, because from the side it seems like in Emacs byte-
> > compiler and interpreter should work in a tandem, as in the example
> > with evaluating (defun hello()). In Emacs context the doc-string that
> > says `Tell the byte-compiler that function FN is defined` would read
> > to
> > me as "modify global state, which later will be read by byte-compiler
> > to deem FN as defined". IOW, to me as a bystander the documentation
> > string does not explain the difference, which is why we just had this
> > somewhat long discussion before I understood why `declare-function`
> > works this way.
> 
> Btw, I just figured out how to show you why this doc-string doesn't say
> anything on the matter. Imagine for a second that `declare-function` is
> getting through from "eval" to the byte-compiler, i.e. the problem
> we're discussing is just not present. Would you change the string `Tell
> the byte-compiler that function FN is defined` to something else in
> this case? I would not, because it's still byte-compiler that does all
> the checking, so the point that "declare-function" is purposed for
> `byte-compiler` stands.

Stefan, any comments or suggestion for how best to document this (if
I'm right)?




This bug report was last modified 73 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.