Subject: bug#55323: 29.0.50; Session-compiled interactive form gives (invalid-function #<symbol list at 476>)

From: Alan Mackenzie <[email-masked]>
Date: Wed, 11 May 2022 15:20:04 +0000

Hello again, Bob.

On Sun, May 08, 2022 at 15:29:12 -0400, Bob Rogers wrote:
> In GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.20, cairo version 1.16.0)
>  of 2022-05-08 built on orion
> Repository revision: 278b18a460caf34e422847d10ac3f0b62bef4996
> Repository branch: master
> Windowing system distributor 'The X.Org Foundation', version 11.0.12003000
> System Description: openSUSE Leap 15.3

>    The problem occurs with an evaluated "interactive" form in a defun
> that is compiled with compile-defun -- and it may have escaped notice
> until now because it doesn't seem to happen if the source is part of
> Emacs (i.e. is compiled in a file that git knows about).

I think what's different is that the source has been copied into a
different file, and that file doesn't have a

    ;; -*- lexical-binding:t -*-

at the top.  :-)

>    1.  emacs -Q

>    2.  Find an elisp file with an interactive form that does not belong
> to an Emacs working copy.  I used the align-highlight-rule snippet
> below, copied from lisp/align.el.

>    3.  Evaluate the first two forms, and do "M-x compile-defun" to
> compile the third.

>    4.  Attempt to invoke the command via "M-x align-highlight-rule RET".

> What you should see then is a backtrace that starts something like this:

> 	Debugger entered--Lisp error: (invalid-function #<symbol list at 476>)
> 	  (#<symbol list at 476> (#<symbol region-beginning at 482>) ...)
> 	  call-interactively(align-highlight-rule record nil)
> 	  command-execute(align-highlight-rule record)

> Disassembly shows that the interactive form is not compiled, and the
> arglist is full of #<symbol X at Y>:

> 	byte code for align-highlight-rule:
> 	  doc:  Highlight the whitespace which a given rule would have modified. ...
> 	  args: (#<symbol beg at 49> #<symbol end at 53> #<symbol title at 57> ...)
> 	 interactive: (#<symbol list at 476> (#<symbol region-beginning at 482>) ...)
> 	0	constant  intern
> 	1	varref	  title
> 	2	call	  1
> 	3	varref	  align-mode-exclude-rules-list

Yes.  For some reason, the interactive form is not compiled when both
lexical-binding is nil AND the form looks like (list .....).  I don't
know why this is, and suspect it's a remnant of a very old bug fix which
is no longer relevant.

> Disassembling the in-tree version, whether from "M-x compile-defun" or
> file compilation, shows neither of these problems (go figure).

See above.

>    And of course "M-x eval-defun" and "M-x byte-compile-file" continue
> to DTRT, so I am not in any hurry for a fix.  TIA,

Would you please try out the following patch, which removes the
positions from the symbols with positions in the arglist and the
interactive form.  Then please let me know how it goes.  Thanks!

diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 28237d67d2..c282d79446 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -3084,7 +3084,8 @@ byte-compile-lambda
                        ;; which may include "calls" to
                        ;; internal-make-closure (Bug#29988).
                        lexical-binding)
-                   (setq int `(,(car int) ,newform)))))
+                   (setq int `(,(car int) ,newform))
+                 (setq int (byte-run-strip-symbol-positions int))))) ; for compile-defun.
             ((cdr int)                  ; Invalid (interactive . something).
 	     (byte-compile-warn-x int "malformed interactive spec: %s"
 				  int))))
@@ -3099,7 +3100,7 @@ byte-compile-lambda
                                         (byte-compile-make-lambda-lexenv
                                          arglistvars))
                                    reserved-csts))
-          (bare-arglist arglist))
+          (bare-arglist (byte-run-strip-symbol-positions arglist))) ; for compile-defun.
       ;; Build the actual byte-coded function.
       (cl-assert (eq 'byte-code (car-safe compiled)))
       (let ((out

> 					-- Bob Rogers
> 					   http://www.rgrjr.com/

-- 
Alan Mackenzie (Nuremberg, Germany).