Subject: Re: bug#41618: 28.0.50; Can't byte-compile an edebugged macro

From: Alan Mackenzie <[email-masked]>
Date: 31 May 2020 17:01:19 -0000

Hello, Philipp.

In article <[email-masked]> you wrote:

> 1. Define some arbitrary macro:

>   (defmacro foo ())

> 2. Edebug it using C-u C-M-x.

This was not actually relevant.  A simple evaluation with C-M-x produces
the same error.

> 3. Attempt to byte-compile it using M-: (byte-compile 'foo).

> This produces an error:

>   Wrong type argument: listp, #[0 "\300\207" [nil] 1]

> The stack trace is

> Debugger entered--Lisp error: (wrong-type-argument listp #f(compiled-function () #<bytecode 0x1e0000171e91>))
>   eval((macro . #f(compiled-function () #<bytecode 0x1e0000171e91>)) t)
>   #f(compiled-function (form) #<bytecode -0x16fada817203f185>)(foo)
>   byte-compile(foo)
>   eval((byte-compile 'foo) t)
>   eval-expression((byte-compile 'foo) nil nil 127)
>   funcall-interactively(eval-expression (byte-compile 'foo) nil nil 127)
>   call-interactively(eval-expression nil nil)
>   command-execute(eval-expression)

This was quite a simple bug.  At the end of byte-compile, the code does
two things:
(i) If the argument to byte-compile is a symbol, the result is eval'd.
(ii) If a macro is being compiled, 'macro is pushed onto the result.

When both of these things were necessary, they were being done in the
wrong order, throwing the error.

I've committed a fix to the emacs-27 branch, and it should reach master
the next time "somebody" copies the commits over.  In the mean time,
here's that patch, should you want to apply it to your system now:

diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 72dbfd74b1..22e648e44b 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -2755,14 +2755,15 @@ byte-compile
         ;; Expand macros.
         (setq fun (byte-compile-preprocess fun))
         (setq fun (byte-compile-top-level fun nil 'eval))
-        (if macro (push 'macro fun))
         (if (symbolp form)
             ;; byte-compile-top-level returns an *expression* equivalent to the
             ;; `fun' expression, so we need to evaluate it, tho normally
             ;; this is not needed because the expression is just a constant
             ;; byte-code object, which is self-evaluating.
-            (fset form (eval fun t))
-          fun)))))))
+            (setq fun (eval fun t)))
+        (if macro (push 'macro fun))
+        (if (symbolp form) (fset form fun))
+        fun))))))
 
 (defun byte-compile-sexp (sexp)
   "Compile and return SEXP."

> In GNU Emacs 28.0.50 (build 19, x86_64-pc-linux-gnu, GTK+ Version 3.24.14, cairo version 1.16.0)
>  of 2020-05-30
> Repository revision: 3dbe6530b124436550dae4db6cd4b7b380e95377
> Repository branch: master
> Windowing system distributor 'The X.Org Foundation', version 11.0.12007000
> System Description: Debian GNU/Linux rodete

[ .... ]

-- 
Alan Mackenzie (Nuremberg, Germany).