Subject: bug#67568: Emacs master: Bug in byte compiler when there's an unused parameter.

From: Alan Mackenzie <[email-masked]>
Date: Fri, 1 Dec 2023 15:22:24 +0000

Hello again, Dmitry.

On Fri, Dec 01, 2023 at 15:06:23 +0200, Dmitry Gutov wrote:
> On 01/12/2023 14:49, Alan Mackenzie wrote:
> > On a recent Emacs master:

> > (i) emacs -Q
> > (ii) In*scratch*  enter the following:

> >      (byte-compile (lambda (x) "doc" "foo"))

> >    .
> > (iii) Enter C-u C-x C-e to evaluate the form.  The result looks like:

> >      #[257 "\300\207" [nil] 2 "doc

> >      (fn X)"]

> >    .  This is incorrect.  The only form in the constants vector is nil.
> >    It should be "foo".

> > (iv) Note that this only happens with the unused parameter x.  Without
> > it, the form compiles correctly.

> Might be a bug in the interpreter too?

> (funcall (lambda (x) "doc" "foo") 2)

> ;; => nil

I have a candidate for the buggy function, namely macroexp-parse-body.
It'd doc string reads "Parse a function BODY into (DECLARATIONS .  EXPS).",
but it's vague about what precisely a BODY is.  It's not clear, either,
what exactly is meant by DECLARATIONS.

What the function does is move strings (or :documentation forms) from the
head of BODY into DECLS.  So maybe DECLARATIONS is intended to be any
number of consecutive doc strings.  Exceptionally, if there is precisely
one string, it is not moved into DECLS.

When BODY is ("doc" "foo") as is the case here, both "doc" and "foo" get
moved from BODY to DECLS, leaving an empty BODY and a wrong DECLS.  The
return value is here (("doc" "foo") . nil), which is clearly wrong.  It
probably should be (("doc") . ("foo")).

-- 
Alan Mackenzie (Nuremberg, Germany).