GNU bug report logs - #78792
[PATCH] Fix compilation of defalias with a constant macro cons pair

Previous Next

Package: emacs;

Reported by: zach shaftel <zach <at> shaf.tel>

Date: Sun, 15 Jun 2025 01:41:02 UTC

Severity: normal

Tags: patch

Done: Eli Zaretskii <eliz <at> gnu.org>

To reply to this bug, email your comments to 78792 AT debbugs.gnu.org.
There is no need to reopen the bug first.

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

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


Report forwarded to shigeru.fukaya <at> gmail.com, bug-gnu-emacs <at> gnu.org:
bug#78792; Package emacs. (Sun, 15 Jun 2025 01:41:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to zach shaftel <zach <at> shaf.tel>:
New bug report received and forwarded. Copy sent to shigeru.fukaya <at> gmail.com, bug-gnu-emacs <at> gnu.org. (Sun, 15 Jun 2025 01:41:02 GMT) Full text and rfc822 format available.

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

From: zach shaftel <zach <at> shaf.tel>
To: bug-gnu-emacs <at> gnu.org
Subject: [PATCH] Fix compilation of defalias with a constant macro cons pair
Date: Sat, 14 Jun 2025 21:40:08 -0400
[Message part 1 (text/plain, inline)]
Tags: patch

byte-compile-file-form-defalias destructures (cons 'macro 'fn) and
'(macro . fn) the same way, so in the latter case fn would be unquoted,
and then eval would later signal (void-variable fn). this patch just
re-quotes fn, and adds a test for this scenario.


In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.49, cairo version 1.18.4) of 2025-06-11 built on bigbox
Repository revision: f90cee6f761b0c2bffcfa64556284884c0f7348f
Repository branch: feature/igc
System Description: Arch Linux

Configured using:
 'configure --with-modules --with-native-compilation --with-tree-sitter
 --without-gsettings --without-gconf --without-gpm --with-pgtk
 --without-compress-install --with-mps 'CFLAGS=-mtune=native
 -march=native -O3 -fuse-ld=mold''

[0001-Fix-compilation-of-defalias-with-a-constant-macro-co.patch (text/patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78792; Package emacs. (Sun, 15 Jun 2025 05:26:05 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: zach shaftel <zach <at> shaf.tel>, Stefan Monnier <monnier <at> iro.umontreal.ca>,
 Mattias Engdegård <mattiase <at> acm.org>,
 Andrea Corallo <acorallo <at> gnu.org>
Cc: 78792 <at> debbugs.gnu.org, shigeru.fukaya <at> gmail.com
Subject: Re: bug#78792: [PATCH] Fix compilation of defalias with a constant
 macro cons pair
Date: Sun, 15 Jun 2025 08:25:11 +0300
> Cc: Shigeru Fukaya <shigeru.fukaya <at> gmail.com>
> Date: Sat, 14 Jun 2025 21:40:08 -0400
> From:  zach shaftel via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> byte-compile-file-form-defalias destructures (cons 'macro 'fn) and
> '(macro . fn) the same way, so in the latter case fn would be unquoted,
> and then eval would later signal (void-variable fn). this patch just
> re-quotes fn, and adds a test for this scenario.

Thanks, I've added the relevant people to this discussion,

> In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
>  3.24.49, cairo version 1.18.4) of 2025-06-11 built on bigbox
> Repository revision: f90cee6f761b0c2bffcfa64556284884c0f7348f
> Repository branch: feature/igc
> System Description: Arch Linux
> 
> Configured using:
>  'configure --with-modules --with-native-compilation --with-tree-sitter
>  --without-gsettings --without-gconf --without-gpm --with-pgtk
>  --without-compress-install --with-mps 'CFLAGS=-mtune=native
>  -march=native -O3 -fuse-ld=mold''
> 
> >From f0b9f227c5711c1cbf7a38c20fd05b184536c12a Mon Sep 17 00:00:00 2001
> From: Zach Shaftel <zach <at> shaf.tel>
> Date: Sat, 14 Jun 2025 20:57:21 -0400
> 
> * lisp/emacs-lisp/bytecomp.el (byte-compile-file-form-defalias): Quote
> the function name in '(macro . function-name), since we eval it later.
> * test/lisp/emacs-lisp/bytecomp-tests.el
> (test-eager-load-macro-expand-defalias): New test.
> ---
>  lisp/emacs-lisp/bytecomp.el            |  3 ++-
>  test/lisp/emacs-lisp/bytecomp-tests.el | 18 ++++++++++++++++++
>  2 files changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
> index 0ec8db214bc..973792c4daa 100644
> --- a/lisp/emacs-lisp/bytecomp.el
> +++ b/lisp/emacs-lisp/bytecomp.el
> @@ -5159,7 +5159,8 @@ byte-compile-file-form-defalias
>         (pcase-let*
>             ;; `macro' is non-nil if it defines a macro.
>             ;; `fun' is the function part of `arg' (defaults to `arg').
> -           (((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let macro t))
> +           (((or (and (or `(cons 'macro ,fun) `'(macro . ,(app (list 'quote) fun)))
> +                      (let macro t))
>                   (and (let fun arg) (let macro nil)))
>               arg)
>              ;; `lam' is the lambda expression in `fun' (or nil if not
> diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
> index 8b0c1dad4c0..b14f10d6eb7 100644
> --- a/test/lisp/emacs-lisp/bytecomp-tests.el
> +++ b/test/lisp/emacs-lisp/bytecomp-tests.el
> @@ -1322,6 +1322,24 @@ test-eager-load-macro-expand-lexical-override
>        (defun def () (m))))
>    (should (equal (funcall 'def) 4)))
>  
> +(ert-deftest test-eager-load-macro-expand-defalias ()
> +  (ert-with-temp-file elfile
> +    :suffix ".el"
> +    (write-region
> +     (concat ";;; -*- lexical-binding: t -*-\n"
> +             (mapconcat #'prin1-to-string
> +                        '((defalias 'nothing '(macro . ignore))
> +                          (defalias 'something (cons 'macro #'identity))
> +                          (defalias 'five (cons 'macro (lambda (&rest _) 5)))
> +                          (eval-when-compile
> +                            (defun def () (or (nothing t) (something (five nil))))))
> +                        "\n"))
> +     nil elfile)
> +    (let* ((byte-compile-debug t)
> +           (byte-compile-dest-file-function #'ignore))
> +      (byte-compile-file elfile)
> +      (should (equal (funcall 'def) 5)))))
> +
>  (defmacro bytecomp-tests--with-temp-file (file-name-var &rest body)
>    (declare (indent 1))
>    (cl-check-type file-name-var symbol)
> -- 
> 2.49.0
> 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78792; Package emacs. (Wed, 18 Jun 2025 08:12:02 GMT) Full text and rfc822 format available.

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

From: Mattias Engdegård <mattias.engdegard <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: shigeru.fukaya <at> gmail.com, Andrea Corallo <acorallo <at> gnu.org>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>, zach shaftel <zach <at> shaf.tel>,
 78792 <at> debbugs.gnu.org
Subject: Re: bug#78792: [PATCH] Fix compilation of defalias with a constant
 macro cons pair
Date: Wed, 18 Jun 2025 10:11:09 +0200
>> byte-compile-file-form-defalias destructures (cons 'macro 'fn) and
>> '(macro . fn) the same way, so in the latter case fn would be unquoted,
>> and then eval would later signal (void-variable fn). this patch just
>> re-quotes fn, and adds a test for this scenario.

This seems to be a genuine bug indeed, thank you for reporting.

>> @@ -5159,7 +5159,8 @@ byte-compile-file-form-defalias
>>        (pcase-let*
>>            ;; `macro' is non-nil if it defines a macro.
>>            ;; `fun' is the function part of `arg' (defaults to `arg').
>> -           (((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let macro t))
>> +           (((or (and (or `(cons 'macro ,fun) `'(macro . ,(app (list 'quote) fun)))
>> +                      (let macro t))
>>                  (and (let fun arg) (let macro nil)))

Patch looks fine as far as I can tell. There is a test (naturally!) as well.






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78792; Package emacs. (Thu, 19 Jun 2025 13:42:05 GMT) Full text and rfc822 format available.

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

From: Pip Cet <pipcet <at> protonmail.com>
To: Mattias Engdegård <mattias.engdegard <at> gmail.com>
Cc: 78792 <at> debbugs.gnu.org, shigeru.fukaya <at> gmail.com,
 zach shaftel <zach <at> shaf.tel>, Stefan Monnier <monnier <at> iro.umontreal.ca>,
 Eli Zaretskii <eliz <at> gnu.org>, Andrea Corallo <acorallo <at> gnu.org>
Subject: Re: bug#78792: [PATCH] Fix compilation of defalias with a constant
 macro cons pair
Date: Thu, 19 Jun 2025 13:41:41 +0000
Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:

>>> byte-compile-file-form-defalias destructures (cons 'macro 'fn) and
>>> '(macro . fn) the same way, so in the latter case fn would be unquoted,
>>> and then eval would later signal (void-variable fn). this patch just
>>> re-quotes fn, and adds a test for this scenario.
>
> This seems to be a genuine bug indeed, thank you for reporting.

Did this occur in the wild or do you have to trigger it deliberately?
I don't think defmacro ever produces a problematic defalias, but maybe
some other macro does?

That's just curiosity, of course.  Both the analysis and the patch seem
correct to me.

>>> @@ -5159,7 +5159,8 @@ byte-compile-file-form-defalias
>>>        (pcase-let*
>>>            ;; `macro' is non-nil if it defines a macro.
>>>            ;; `fun' is the function part of `arg' (defaults to `arg').
>>> -           (((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let macro t))
>>> +           (((or (and (or `(cons 'macro ,fun) `'(macro . ,(app (list 'quote) fun)))
>>> +                      (let macro t))
>>>                  (and (let fun arg) (let macro nil)))
>
> Patch looks fine as far as I can tell. There is a test (naturally!) as well.

TBH, I had to look up the (app F X) pcase pattern.  I think that means
we should use it more, not less, so people will become used to it and
stop emulating it badly, which is what I've done so far...

The rest of this email is relevant only because we should maybe just
delete this code instead of fixing it:

We should have a hard look at whether this function makes sense in its
current form: if we can't parse/compile a defalias form, and it defined
a function, that's okay.  But if we can't compile it and it defined a
macro, shouldn't that be a fatal error?

And since we can't tell whether a Lisp expression evaluates to a macro
definition or a function definition, maybe it's time to handle the
remaining common cases only and make the rest errors (which is okay, not
every conceivable Elisp program can be byte-compiled)?

Here's an example which we miscompile (make sure NOT to evaluate this in
the session which then compiles it):

;; -*- lexical-binding: t; -*-
(defalias 'mybq3 (symbol-function '\`))
(message "%S" (mybq3 (,3)))

Pip





Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Sat, 21 Jun 2025 08:42:02 GMT) Full text and rfc822 format available.

Notification sent to zach shaftel <zach <at> shaf.tel>:
bug acknowledged by developer. (Sat, 21 Jun 2025 08:42:02 GMT) Full text and rfc822 format available.

Message #19 received at 78792-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Mattias Engdegård <mattias.engdegard <at> gmail.com>
Cc: shigeru.fukaya <at> gmail.com, acorallo <at> gnu.org, monnier <at> iro.umontreal.ca,
 zach <at> shaf.tel, 78792-done <at> debbugs.gnu.org
Subject: Re: bug#78792: [PATCH] Fix compilation of defalias with a constant
 macro cons pair
Date: Sat, 21 Jun 2025 11:41:42 +0300
> From: Mattias Engdegård <mattias.engdegard <at> gmail.com>
> Date: Wed, 18 Jun 2025 10:11:09 +0200
> Cc: zach shaftel <zach <at> shaf.tel>,
>  Stefan Monnier <monnier <at> iro.umontreal.ca>,
>  Andrea Corallo <acorallo <at> gnu.org>,
>  78792 <at> debbugs.gnu.org,
>  shigeru.fukaya <at> gmail.com
> 
> >> byte-compile-file-form-defalias destructures (cons 'macro 'fn) and
> >> '(macro . fn) the same way, so in the latter case fn would be unquoted,
> >> and then eval would later signal (void-variable fn). this patch just
> >> re-quotes fn, and adds a test for this scenario.
> 
> This seems to be a genuine bug indeed, thank you for reporting.
> 
> >> @@ -5159,7 +5159,8 @@ byte-compile-file-form-defalias
> >>        (pcase-let*
> >>            ;; `macro' is non-nil if it defines a macro.
> >>            ;; `fun' is the function part of `arg' (defaults to `arg').
> >> -           (((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let macro t))
> >> +           (((or (and (or `(cons 'macro ,fun) `'(macro . ,(app (list 'quote) fun)))
> >> +                      (let macro t))
> >>                  (and (let fun arg) (let macro nil)))
> 
> Patch looks fine as far as I can tell. There is a test (naturally!) as well.

Thanks for the review; now installed on the master branch, and closing
the bug.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78792; Package emacs. (Sat, 05 Jul 2025 15:00:04 GMT) Full text and rfc822 format available.

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

From: Mattias Engdegård <mattias.engdegard <at> gmail.com>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: 78792 <at> debbugs.gnu.org, shigeru.fukaya <at> gmail.com,
 zach shaftel <zach <at> shaf.tel>, Stefan Monnier <monnier <at> iro.umontreal.ca>,
 Eli Zaretskii <eliz <at> gnu.org>, Andrea Corallo <acorallo <at> gnu.org>
Subject: Re: bug#78792: [PATCH] Fix compilation of defalias with a constant
 macro cons pair
Date: Sat, 5 Jul 2025 16:58:54 +0200
19 juni 2025 kl. 15.41 skrev Pip Cet <pipcet <at> protonmail.com>:

> Did this occur in the wild or do you have to trigger it deliberately?
> I don't think defmacro ever produces a problematic defalias, but maybe
> some other macro does?

Yes, I was curious about that, too. So back to Zach: what prompted this bug report?

> TBH, I had to look up the (app F X) pcase pattern.  I think that means
> we should use it more, not less, so people will become used to it and
> stop emulating it badly, which is what I've done so far...

Only used it for defining new pcase macros myself, but very useful for that.
I've tried to avoid it in plain code because it often becomes a bit too clever.

> We should have a hard look at whether this function makes sense in its
> current form: if we can't parse/compile a defalias form, and it defined
> a function, that's okay.  But if we can't compile it and it defined a
> macro, shouldn't that be a fatal error?

Yes, I'd prefer that. In particular, the

                 (message "Macro %s unrecognized, won't work in file" name)
               (message "Macro %s partly recognized, trying our luck" name)

messages aren't helpful. Because they aren't warnings or errors, they are likely to be lost in the compilation log without the user ever knowing about it, and even if seen there's no location to help pinpoint the problem.

I'd prefer a warning (with location) for both cases. I doubt it would trigger for useful code that cannot be written in some other way.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78792; Package emacs. (Sat, 05 Jul 2025 18:17:02 GMT) Full text and rfc822 format available.

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

From: zach shaftel <zach <at> shaf.tel>
To: Mattias Engdegård <mattias.engdegard <at> gmail.com>
Cc: Pip Cet <pipcet <at> protonmail.com>, 78792 <at> debbugs.gnu.org,
 shigeru.fukaya <at> gmail.com, Stefan Monnier <monnier <at> iro.umontreal.ca>,
 Eli Zaretskii <eliz <at> gnu.org>, Andrea Corallo <acorallo <at> gnu.org>
Subject: Re: bug#78792: [PATCH] Fix compilation of defalias with a constant
 macro cons pair
Date: Sat, 05 Jul 2025 14:16:17 -0400
Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:

> 19 juni 2025 kl. 15.41 skrev Pip Cet <pipcet <at> protonmail.com>:
>
>> Did this occur in the wild or do you have to trigger it deliberately?
>> I don't think defmacro ever produces a problematic defalias, but maybe
>> some other macro does?
>
> Yes, I was curious about that, too. So back to Zach: what prompted this bug report?

i wrote a `comment' macro (defalias 'comment '(macro . ignore)), mainly
for amusement, and to see if it would break anything. so i guess that
experiment was successful.

>> TBH, I had to look up the (app F X) pcase pattern.  I think that means
>> we should use it more, not less, so people will become used to it and
>> stop emulating it badly, which is what I've done so far...
>
> Only used it for defining new pcase macros myself, but very useful for that.
> I've tried to avoid it in plain code because it often becomes a bit
> too clever.

interesting, i use that pattern quite often. i definitely abuse pcase at
times, but it can express some things more succinctly than other
patterns, eg. (or `(,car . ,_) (let car nil)) vs (app car-safe car),
which incidentally produces a much simpler macroexpansion.

>
>> We should have a hard look at whether this function makes sense in its
>> current form: if we can't parse/compile a defalias form, and it defined
>> a function, that's okay.  But if we can't compile it and it defined a
>> macro, shouldn't that be a fatal error?
>
> Yes, I'd prefer that. In particular, the
>
>                  (message "Macro %s unrecognized, won't work in file" name)
>                (message "Macro %s partly recognized, trying our luck" name)
>
> messages aren't helpful. Because they aren't warnings or errors, they
> are likely to be lost in the compilation log without the user ever
> knowing about it, and even if seen there's no location to help
> pinpoint the problem.
>
> I'd prefer a warning (with location) for both cases. I doubt it would
> trigger for useful code that cannot be written in some other way.

i agree. replacing defalias with eval-and-compile + fset works as
expected and doesn't seem to break anything, but we should nag the user
if they're writing code that way.

-zach




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78792; Package emacs. (Mon, 07 Jul 2025 09:20:02 GMT) Full text and rfc822 format available.

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

From: Mattias Engdegård <mattias.engdegard <at> gmail.com>
To: zach shaftel <zach <at> shaf.tel>
Cc: Pip Cet <pipcet <at> protonmail.com>, 78792 <at> debbugs.gnu.org,
 shigeru.fukaya <at> gmail.com, Stefan Monnier <monnier <at> iro.umontreal.ca>,
 Eli Zaretskii <eliz <at> gnu.org>, Andrea Corallo <acorallo <at> gnu.org>
Subject: Re: bug#78792: [PATCH] Fix compilation of defalias with a constant
 macro cons pair
Date: Mon, 7 Jul 2025 11:18:50 +0200
>>                 (message "Macro %s unrecognized, won't work in file" name)
>>               (message "Macro %s partly recognized, trying our luck" name)

Now these are compiler warnings instead, to make them more visible and get a location. I didn't change the somewhat opaque wording but if someone wants to do that I won't complain.





This bug report was last modified 10 days ago.

Previous Next


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