GNU bug report logs - #51982
Erroneous handling of local variables in byte-compiled nested lambdas

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: Paul Pogonyshev <pogonyshev@HIDDEN>; Keywords: patch; dated Fri, 19 Nov 2021 20:32:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 2 Dec 2021 09:13:45 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Dec 02 04:13:45 2021
Received: from localhost ([127.0.0.1]:46561 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1msi9x-0006jn-Et
	for submit <at> debbugs.gnu.org; Thu, 02 Dec 2021 04:13:45 -0500
Received: from mail212c50.megamailservers.eu ([91.136.10.222]:36806
 helo=mail194c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1msi9v-0006jY-80
 for 51982 <at> debbugs.gnu.org; Thu, 02 Dec 2021 04:13:44 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1638436415;
 bh=DB2VTS4XXFrvhGy5+4dlvken3wDoVvqeR2IMQF2ee2Q=;
 h=Subject:From:In-Reply-To:Date:Cc:References:To:From;
 b=dXEGsleGs/oLYMp1f5QJsA68aPjFkojbQGjBryf3ixJJ5/v6R1AbzPcJqSMEnDBWK
 Mw9QLX+9mUaO7JUAGOENWzsePJQyaz37fXlex2HnXz0tuWRsYG7fh7b4uahOnKNECB
 EvBLSr6qeGtdIiZkGCSKLU+JaDjNgVDX9B/Up3y0=
Feedback-ID: mattiase@HIDDEN
Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se
 [83.227.82.185]) (authenticated bits=0)
 by mail194c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1B29DV9S022584; 
 Thu, 2 Dec 2021 09:13:33 +0000
Content-Type: text/plain;
	charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
In-Reply-To: <6EA55EF4-D5B2-490E-B1FF-DC86A034C893@HIDDEN>
Date: Thu, 2 Dec 2021 10:13:31 +0100
Content-Transfer-Encoding: quoted-printable
Message-Id: <B846CFD8-D288-407D-B479-DD21970823DB@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
 <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
 <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
 <B51CEFD1-DFDF-4C78-93AB-254278776E47@HIDDEN>
 <jwvlf152tqb.fsf-monnier+emacs@HIDDEN>
 <AF81C637-59D9-468B-917F-65AC37B13C75@HIDDEN>
 <jwvr1awyyuo.fsf-monnier+emacs@HIDDEN>
 <6EA55EF4-D5B2-490E-B1FF-DC86A034C893@HIDDEN>
To: Stefan Monnier <monnier@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F27.61A88E3F.005D, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=Dv41REz+ c=1 sm=1 tr=0 ts=61a88e3f
 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17
 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=NB-phzwo78Iuget5PpkA:9
 a=CjuIK1q_8ugA:10
X-Origin-Country: SE
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

> Yes, and I can confirm that both transformations (let* -> let and the =
inverse) seem to generate almost or exactly identical bytecode for =
lexbind code. If you can find an example where it's worse, I'd like to =
know.

And by "yes" I mean "no", since the identical bytecode is only true in =
the absence of mutation which, as always, throws a spanner in the works. =
For example, while

(let ((x (sin y)) (y (cos x)))
  (+ x y))))
->
(let* ((x0 (sin y)) (y (cos x)) (x x0))
  (+ x y))))

is a transformation with identical bytecode, mutating one of the =
variables:

(let ((x (sin y)) (y (cos x)))
  (setq x (1+ x))
  (+ x y))))
->
(let* ((x0 (sin y)) (y (cos x)) (x x0))
  (setq x (1+ x))
  (+ x y))))

will prevent the intermediate from being eliminated. Not a disaster by =
any means but not good enough as a general method of translation.





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 1 Dec 2021 22:32:57 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Dec 01 17:32:57 2021
Received: from localhost ([127.0.0.1]:46025 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1msY9p-0008Ue-Jp
	for submit <at> debbugs.gnu.org; Wed, 01 Dec 2021 17:32:57 -0500
Received: from mail239c50.megamailservers.eu ([91.136.10.249]:46100
 helo=mail56c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1msY9n-0008UR-EC
 for 51982 <at> debbugs.gnu.org; Wed, 01 Dec 2021 17:32:56 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1638397973;
 bh=LQKYk65KJuyg4hyfr6xgoYanMuCeynhfM5v5ryh5OBk=;
 h=Subject:From:In-Reply-To:Date:Cc:References:To:From;
 b=hybuFOA11e4LI21sVww4eAK1fWBWnculRTK09vFzbO4fstddpQ9YtHzobqXPDgk8T
 2Gh9nXU+o4PlEzTj3siDGIWWYJL8yHjjYwEhJHB3Z7j3hA37xRSfSse8mCvSNvok0z
 +kl9xeKHwqH2phzzP3OXc1sAo6+SdJSHBCR1RW28=
Feedback-ID: mattiase@HIDDEN
Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se
 [83.227.82.185]) (authenticated bits=0)
 by mail56c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1B1MWoee014055; 
 Wed, 1 Dec 2021 22:32:51 +0000
Content-Type: text/plain;
	charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
In-Reply-To: <jwvr1awyyuo.fsf-monnier+emacs@HIDDEN>
Date: Wed, 1 Dec 2021 23:32:49 +0100
Content-Transfer-Encoding: quoted-printable
Message-Id: <6EA55EF4-D5B2-490E-B1FF-DC86A034C893@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
 <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
 <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
 <B51CEFD1-DFDF-4C78-93AB-254278776E47@HIDDEN>
 <jwvlf152tqb.fsf-monnier+emacs@HIDDEN>
 <AF81C637-59D9-468B-917F-65AC37B13C75@HIDDEN>
 <jwvr1awyyuo.fsf-monnier+emacs@HIDDEN>
To: Stefan Monnier <monnier@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F1E.61A7F815.0007, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=G/d/r/o5 c=1 sm=1 tr=0 ts=61a7f815
 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17
 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=iRZporoAAAAA:8
 a=DOUPeibL_tSTObFTsK4A:9 a=CjuIK1q_8ugA:10 a=NOBgFS-JBQ2l-kSd6-zu:22
X-Origin-Country: SE
X-Spam-Score: 1.4 (+)
X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org",
 has NOT identified this incoming email as spam.  The original
 message has been attached to this so you can view it or label
 similar future email.  If you have any questions, see
 the administrator of that system for details.
 Content preview: 1 dec. 2021 kl. 19.34 skrev Stefan Monnier
 <monnier@HIDDEN>:
 >>> BTW, have you checked the impact on byte-code quality? >> With respect
 to these patches? > > No I meant w.r.t removing `let*` (or `let` as the case
 may be). 
 Content analysis details:   (1.4 points, 10.0 required)
 pts rule name              description
 ---- ---------------------- --------------------------------------------------
 0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record
 1.0 SPF_SOFTFAIL           SPF: sender does not match SPF record (softfail)
 0.4 KHOP_HELO_FCRDNS       Relay HELO differs from its IP's reverse DNS
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

1 dec. 2021 kl. 19.34 skrev Stefan Monnier <monnier@HIDDEN>:

>>> BTW, have you checked the impact on byte-code quality?
>> With respect to these patches?
>=20
> No I meant w.r.t removing `let*` (or `let` as the case may be).

Yes, and I can confirm that both transformations (let* -> let and the =
inverse) seem to generate almost or exactly identical bytecode for =
lexbind code. If you can find an example where it's worse, I'd like to =
know.

>>> Also, If mapping is of the form (car-safe SYMBOL) is `var` really =
the
>>> correct answer?  Shouldn't it still be (cadr mapping)?
>> Can there ever be a difference?
>=20
> There's a big philosophical difference, yes.

We could declare it an invariant and add an assertion.

> I think another way to do the patch B would be to replace `var` with
> `lifted` right when we construct the (apply-partially ...) thingy
> (i.e. in the :lambda-candidate part of the function), so those vars =
that
> get remapped to `internal-get-closed-var` wouldn't even make their way
> to `extend`.

Yes, that would probably be even cleaner. Then we wouldn't need to worry =
about shadowing for those.
I'm not going to do more experimenting with it now but do try it if it =
makes the code better.

By the way, I did try constant-propagating `(internal-get-closed-var N)` =
but got less yield than I hoped for. I'll look closer, maybe I made a =
silly mistake.

>> Good comments, thank you very much!
>=20
> [ I resent this implicit suggestion that I could ever write something =
less
>  than a good comment.  ]

That wasn't for your consumption but to inform the unwashed masses who =
can't tell the difference!





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 1 Dec 2021 18:34:12 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Dec 01 13:34:12 2021
Received: from localhost ([127.0.0.1]:45601 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1msUQm-0005ce-Dg
	for submit <at> debbugs.gnu.org; Wed, 01 Dec 2021 13:34:12 -0500
Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:49505)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <monnier@HIDDEN>) id 1msUQk-0005cR-SI
 for 51982 <at> debbugs.gnu.org; Wed, 01 Dec 2021 13:34:11 -0500
Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1])
 by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id A07EF4413E9;
 Wed,  1 Dec 2021 13:34:04 -0500 (EST)
Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1])
 by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id D51984413D8;
 Wed,  1 Dec 2021 13:34:02 -0500 (EST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca;
 s=mail; t=1638383642;
 bh=gWcGXHoXNByaNMtXJj0XsN7V8JBTUgFZoCckbjg3Xy8=;
 h=From:To:Cc:Subject:References:Date:In-Reply-To:From;
 b=CK/qdKAT/7GRGBQz8WpBsy64BFGOHW+Wb9oFozpm+7o4TOKlnC7YWN6SL1LxeuaZM
 ULNvsYYIbT+GUlGXom9KoLa+4ZgYnCGKg5mBlMsv350PVHQ0jZGMJi9Xgk1EhXVR8v
 jwnwm2LcGe+KuhW7S/DatcYtH31Z6XS76uKsbQQZdx7PHg7w5gq5Gz7iaYEk9ppppq
 jIKBg5Fmb4AMimLfjK5ZplRtUSomTxzC8MqrkTBmQC2hPIFnmCO/a4JZ5f1gqzKNkK
 WxzVJ0WNmzpjN5siFrRVjN6JGSnFc9a/x54vSv8LsxLVMw9TWR+2ishXi4OCpgqwfO
 t3TVuZOBUh/pw==
Received: from alfajor (lechon.iro.umontreal.ca [132.204.27.242])
 by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id B0FC91209CF;
 Wed,  1 Dec 2021 13:34:02 -0500 (EST)
From: Stefan Monnier <monnier@HIDDEN>
To: Mattias =?windows-1252?Q?Engdeg=E5rd?= <mattiase@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in
 byte-compiled nested lambdas
Message-ID: <jwvr1awyyuo.fsf-monnier+emacs@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
 <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
 <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
 <B51CEFD1-DFDF-4C78-93AB-254278776E47@HIDDEN>
 <jwvlf152tqb.fsf-monnier+emacs@HIDDEN>
 <AF81C637-59D9-468B-917F-65AC37B13C75@HIDDEN>
Date: Wed, 01 Dec 2021 13:34:01 -0500
In-Reply-To: <AF81C637-59D9-468B-917F-65AC37B13C75@HIDDEN> ("Mattias
 =?windows-1252?Q?Engdeg=E5rd=22's?= message of "Wed, 1 Dec 2021 17:04:44
 +0100")
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain
X-SPAM-INFO: Spam detection results:  0
 ALL_TRUSTED                -1 Passed through trusted hosts only via SMTP
 AWL 0.151 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily valid
 DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature
 DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's
 domain
X-SPAM-LEVEL: 
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

>> BTW, have you checked the impact on byte-code quality?
> With respect to these patches?

No I meant w.r.t removing `let*` (or `let` as the case may be).

> Yes: the B patch gives slightly better code because materialising the
> accessor (internal-get-closed-var N) is as cheap or cheaper than even
> a stack variable access. But the difference is small and since the
> case is rare it's probably insignificant.

I'm not worried at all about the performance of this corner-case.

>> Also, If mapping is of the form (car-safe SYMBOL) is `var` really the
>> correct answer?  Shouldn't it still be (cadr mapping)?
> Can there ever be a difference?

There's a big philosophical difference, yes.

>> Side note: I don't understand why we `(cons closedsym`, since that
>> `closedsym` can never appear in another binding (since it's fresh).
> Maybe it's to satisfy the invariant checked by the assertion at the top?

I don't think so because this one just checks that the
`cconv--remap-llv` was called where needed and did its job.

... [ goes and removes that `(cons closedsym` ] ...
... [ `make` ] ...

Oh, you're right!

>> I don't much like this `symbolp` test (which fundamentally seems to
>> be trying to recover the information about which branch of the `pcase`
>> we're coming from in `cconv--lifted-arg`).
> That's precisely what it is trying to do and no, I don't like it much either.

I think another way to do the patch B would be to replace `var` with
`lifted` right when we construct the (apply-partially ...) thingy
(i.e. in the :lambda-candidate part of the function), so those vars that
get remapped to `internal-get-closed-var` wouldn't even make their way
to `extend`.

> I don't see any alternative that is obviously better so I'm applying patch
> A. We can still go with B later on if we want; the changes are minor.

Good.

> Good comments, thank you very much!

[ I resent this implicit suggestion that I could ever write something less
  than a good comment.  ]


        Stefan





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 1 Dec 2021 16:04:58 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Dec 01 11:04:58 2021
Received: from localhost ([127.0.0.1]:45328 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1msS6M-0007r0-61
	for submit <at> debbugs.gnu.org; Wed, 01 Dec 2021 11:04:58 -0500
Received: from mail1478c50.megamailservers.eu ([91.136.14.78]:38588
 helo=mail118c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1msS6J-0007qj-0X
 for 51982 <at> debbugs.gnu.org; Wed, 01 Dec 2021 11:04:56 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1638374687;
 bh=mVFFMflD9NAw+XbHn/fXaPHb8ePSAtJZ6dN6fg0bknM=;
 h=Subject:From:In-Reply-To:Date:Cc:References:To:From;
 b=GfvG9efpZvO3DfL//hVScdVxeiOKtb6YJegWPPCMbBZAoK3A0ivB5Owm9i4D2X+IF
 IO/GSXA1tCGCaU2l1Z48Ek4beM8EpkvjorhAHDZBAzt6OUbAj9j1r3onpDHGG/UFp8
 UC8gOw4thWbRoG2RqWu9B7lIHrk/YBaHT86IgQ4g=
Feedback-ID: mattiase@HIDDEN
Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se
 [83.227.82.185]) (authenticated bits=0)
 by mail118c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1B1G4iLb020180; 
 Wed, 1 Dec 2021 16:04:46 +0000
Content-Type: text/plain;
	charset=utf-8
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
In-Reply-To: <jwvlf152tqb.fsf-monnier+emacs@HIDDEN>
Date: Wed, 1 Dec 2021 17:04:44 +0100
Content-Transfer-Encoding: quoted-printable
Message-Id: <AF81C637-59D9-468B-917F-65AC37B13C75@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
 <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
 <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
 <B51CEFD1-DFDF-4C78-93AB-254278776E47@HIDDEN>
 <jwvlf152tqb.fsf-monnier+emacs@HIDDEN>
To: Stefan Monnier <monnier@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F19.61A79D1F.00DD, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=M80ulw8s c=1 sm=1 tr=0 ts=61a79d1f
 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17
 a=IkcTkHD0fZMA:10 a=M51BFTxLslgA:10 a=iRZporoAAAAA:8
 a=cfH4NIlj4eTF1UUExc8A:9 a=QEXdDO2ut3YA:10 a=NOBgFS-JBQ2l-kSd6-zu:22
X-Origin-Country: SE
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

30 nov. 2021 kl. 23.41 skrev Stefan Monnier <monnier@HIDDEN>:

> [ We could also force dynamically-scoped code to go through (a =
neutered
>  version of) cconv.el , so that bytecomp.el and byte-opt.el can =
presume
>  that `let*` doesn't exist any more.  ]

Yes, a dynbind frontend would be handy for other reasons (some syntactic =
normalisation in case we can't do in macroexpand-all).=20

> BTW, have you checked the impact on byte-code quality?

With respect to these patches? Yes: the B patch gives slightly better =
code because materialising the accessor (internal-get-closed-var N) is =
as cheap or cheaper than even a stack variable access. But the =
difference is small and since the case is rare it's probably =
insignificant.

In fact, there is probably a way of making them produce identical code =
by constant-propagating such forms in the optimiser. Who knows, might =
give unexpected improvements to existing code as well. Time for an =
experiment!

>>> These two tests are identical aren't they?
>> No, they exercise different code paths (let and let*).
>=20
> Then that deserves a comment ;-)

Will do.

>>> Looks good (better than patch A).
>>=20
>> And here I was prepared to apply patch A since it's slightly more
>> conservative and it seems to be a rare problem anyway.
>> I've now split the patches in a more sensible (and easily reviewed) =
way: the
>> first corresponds to patch A, and the second is the diff to B. Take a =
second
>> look before making up your mind.
>>=20
>>> You say "On the other hand, patch B does abuse the cconv data =
structures
>>> a little (but it works!)" so the code should say something about
>>> this abuse.  A least I failed to see where the abuse lies.
>>=20
>> There are comments and doc strings such as
>>=20
>>  EXTEND is a list of variables which might need to be accessed even
>>  from places where they are shadowed, because some part of ENV causes
>>  them to be used at places where they originally did not
>>  directly appear.
>>=20
>> but with the B patch we put things into `extend` that are not =
strictly
>> variables but (international-get-closed-var N).
>=20
> See below, I think we don't need to put them there.
>=20
>> Similarly, `env` has entries like (VAR . (apply-partially F ARG1 ARG2 =
..))
>> where the ARGi are always treated as variables but now they can be =
access
>> forms as well.
>=20
> I don't think the current code assumes that ARGs are vars here.
> You're probably right that it used to be the case and it's not any =
more,
> but that shouldn't cause problems.  The risk I can see is if one of
> those ARGs is an expression which refers to a var which gets shadowed,
> in which case `cconv--remap-llv` won't rewrite it the way it should.
> But I think with your code ARG will either be a simple var or =
something
> of the form (internal-get-closed-var N) so we should be safe.
>=20
>> @@ -304,6 +304,22 @@ cconv--convert-funcbody
>>             `(,@(nreverse special-forms) ,@(macroexp-unprogn body))))
>>       funcbody)))
>>=20
>> +(defun cconv--lifted-arg (var env)
>> +  "The argument to use for VAR in =CE=BB-lifted calls according to =
ENV."
>> +  (let ((mapping (cdr (assq var env))))
>> +    (pcase-exhaustive mapping
>> +      (`(internal-get-closed-var . ,_)
>> +       ;; The variable is captured.
>> +       mapping)
>> +      (`(car-safe (internal-get-closed-var . ,_))
>> +       ;; The variable is mutably captured; skip
>> +       ;; the indirection step because the variable is
>> +       ;; passed "by reference" to the =CE=BB-lifted function.
>> +       (cadr mapping))
>> +      ((or '() `(car-safe ,(pred symbolp)))
>> +       ;; The variable is not captured; use the (shadowed) variable =
value.
>> +       var))))
>=20
> The docstring or comment at the beginning should mention this function
> is specifically for shadowed vars.

Right.

> Also, If mapping is of the form (car-safe SYMBOL) is `var` really the
> correct answer?  Shouldn't it still be (cadr mapping)?

Can there ever be a difference? I don't think so, but prove me wrong!
(If you manage to do that, you will have found a second bug in the =
original code.)

For context, this is the case when we have a variable mutated by a =
lambda lifted inner function (that doesn't escape). The variable will be =
wrapped in a cons but retain its name. Example:

(lambda (x)
  (let ((f (lambda () (setq x (1+ x)))))
    (let ((x 3))
      (list x (funcall f)))))
->
(lambda (x)
  (let ((x (list x)))=20
    (let ((f (lambda (x) (setcar x (1+ (car-safe x))))))
      (let ((x 3)
            (closed-x x))
        (list x (funcall f closed-x))))))

> Side note: I don't understand why we `(cons closedsym`, since that
> `closedsym` can never appear in another binding (since it's fresh).

Maybe it's to satisfy the invariant checked by the assertion at the top?

> I don't much like this `symbolp` test (which fundamentally seems to
> be trying to recover the information about which branch of the `pcase`
> we're coming from in `cconv--lifted-arg`).

That's precisely what it is trying to do and no, I don't like it much =
either.

I suppose cconv--lifted-arg could be made a location function; we could =
then access and mutate local variables. Something poetically =
self-referential about that, but I'm not overly fond of the closure =
creation overhead (better than what it once was but still too high).

>  It at least deserves
> a comment explaining why it's doing the right thing.

> If we can remove this `symbolp` test recovering info about provenance =
of
> the result of `cconv--lifted-arg` then I think option B is better, but
> I prefer otherwise option A.

I don't see any alternative that is obviously better so I'm applying =
patch A. We can still go with B later on if we want; the changes are =
minor.

Good comments, thank you very much!






Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 30 Nov 2021 22:42:04 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Nov 30 17:42:04 2021
Received: from localhost ([127.0.0.1]:42762 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1msBp5-0000xw-Ng
	for submit <at> debbugs.gnu.org; Tue, 30 Nov 2021 17:42:04 -0500
Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:53865)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <monnier@HIDDEN>) id 1msBp3-0000xP-7U
 for 51982 <at> debbugs.gnu.org; Tue, 30 Nov 2021 17:42:02 -0500
Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1])
 by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 20A5D100164;
 Tue, 30 Nov 2021 17:41:55 -0500 (EST)
Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1])
 by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id BF3F210000D;
 Tue, 30 Nov 2021 17:41:52 -0500 (EST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca;
 s=mail; t=1638312112;
 bh=Hlu2sMLfwIK6EWBBUxUhtUOt36Q8eiYHsXn7Crm0ns8=;
 h=From:To:Cc:Subject:References:Date:In-Reply-To:From;
 b=cpcIxPVv4HMe2CTkOYPSKZ/rLt1zVHx+7EHUQWHLwXgD4IDaR5+BR1bgY/+hcwww8
 +Zqry2Ez8V0Ta6XxPYTpNobcO2L7B6m0As7XlJcNIx6ArB4PPDSIqT838U4Xp2agM4
 7NtJrYvRdthWI80p5Hnd3pC5Iy8vYgy0iPTDOh2O9L6QpdrrBEFkWEuBBDk27YzstY
 k3RxGLC8OU9Tehgrm1mpgNawAg36PRpks1igjx8HXVDuXwNYGOtvnxaMA58gpW9s3h
 d+oId+4VGd/P6ULL9sbVMlCMqfcnNVW+hanStIlvsoVnZZ81VsgB8Q/R1LK7x6+jii
 eu61/pBEb2XBg==
Received: from alfajor (lechon.iro.umontreal.ca [132.204.27.242])
 by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 9A9B312069F;
 Tue, 30 Nov 2021 17:41:52 -0500 (EST)
From: Stefan Monnier <monnier@HIDDEN>
To: Mattias =?windows-1252?Q?Engdeg=E5rd?= <mattiase@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in
 byte-compiled nested lambdas
Message-ID: <jwvlf152tqb.fsf-monnier+emacs@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
 <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
 <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
 <B51CEFD1-DFDF-4C78-93AB-254278776E47@HIDDEN>
Date: Tue, 30 Nov 2021 17:41:51 -0500
In-Reply-To: <B51CEFD1-DFDF-4C78-93AB-254278776E47@HIDDEN> ("Mattias
 =?windows-1252?Q?Engdeg=E5rd=22's?= message of "Tue, 30 Nov 2021 18:01:59
 +0100")
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-SPAM-INFO: Spam detection results:  0
 ALL_TRUSTED                -1 Passed through trusted hosts only via SMTP
 AWL 0.144 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily valid
 DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature
 DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's
 domain
X-SPAM-LEVEL: 
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

> (Really want to get rid of `let*`!)

FWIW, we could get rid of it in `cconv-convert`.
That would have less impact than doing it in macroexpansion.

[ We could also force dynamically-scoped code to go through (a neutered
  version of) cconv.el , so that bytecomp.el and byte-opt.el can presume
  that `let*` doesn't exist any more.  ]

Tho maybe we'd want to eliminate `let` instead.  ;-)

BTW, have you checked the impact on byte-code quality?

>> These two tests are identical aren't they?
> No, they exercise different code paths (let and let*).

Then that deserves a comment ;-)

>> Looks good (better than patch A).
>
> And here I was prepared to apply patch A since it's slightly more
> conservative and it seems to be a rare problem anyway.
> I've now split the patches in a more sensible (and easily reviewed) way: =
the
> first corresponds to patch A, and the second is the diff to B. Take a sec=
ond
> look before making up your mind.
>
>> You say "On the other hand, patch B does abuse the cconv data structures
>> a little (but it works!)" so the code should say something about
>> this abuse.  A least I failed to see where the abuse lies.
>
> There are comments and doc strings such as
>
>   EXTEND is a list of variables which might need to be accessed even
>   from places where they are shadowed, because some part of ENV causes
>   them to be used at places where they originally did not
>   directly appear.
>
> but with the B patch we put things into `extend` that are not strictly
> variables but (international-get-closed-var N).

See below, I think we don't need to put them there.

> Similarly, `env` has entries like (VAR . (apply-partially F ARG1 ARG2 ..))
> where the ARGi are always treated as variables but now they can be access
> forms as well.

I don't think the current code assumes that ARGs are vars here.
You're probably right that it used to be the case and it's not any more,
but that shouldn't cause problems.  The risk I can see is if one of
those ARGs is an expression which refers to a var which gets shadowed,
in which case `cconv--remap-llv` won't rewrite it the way it should.
But I think with your code ARG will either be a simple var or something
of the form (internal-get-closed-var N) so we should be safe.

> @@ -304,6 +304,22 @@ cconv--convert-funcbody
>              `(,@(nreverse special-forms) ,@(macroexp-unprogn body))))
>        funcbody)))
>=20=20
> +(defun cconv--lifted-arg (var env)
> +  "The argument to use for VAR in =CE=BB-lifted calls according to ENV."
> +  (let ((mapping (cdr (assq var env))))
> +    (pcase-exhaustive mapping
> +      (`(internal-get-closed-var . ,_)
> +       ;; The variable is captured.
> +       mapping)
> +      (`(car-safe (internal-get-closed-var . ,_))
> +       ;; The variable is mutably captured; skip
> +       ;; the indirection step because the variable is
> +       ;; passed "by reference" to the =CE=BB-lifted function.
> +       (cadr mapping))
> +      ((or '() `(car-safe ,(pred symbolp)))
> +       ;; The variable is not captured; use the (shadowed) variable valu=
e.
> +       var))))

The docstring or comment at the beginning should mention this function
is specifically for shadowed vars.

Also, If mapping is of the form (car-safe SYMBOL) is `var` really the
correct answer?  Shouldn't it still be (cadr mapping)?

>  (defun cconv-convert (form env extend)
>    ;; This function actually rewrites the tree.
>    "Return FORM with all its lambdas changed so they are closed.
> @@ -428,10 +444,11 @@ cconv-convert
>                   ;; One of the lambda-lifted vars is shadowed, so add
>                   ;; a reference to the outside binding and arrange to use
>                   ;; that reference.
> -                 (let ((closedsym (make-symbol (format "closed-%s" var))=
))
> +                 (let ((var-def (cconv--lifted-arg var env))
> +                       (closedsym (make-symbol (format "closed-%s" var))=
))
>                     (setq new-env (cconv--remap-llv new-env var closedsym=
))
>                     (setq new-extend (cons closedsym (remq var new-extend=
)))
> -                   (push `(,closedsym ,var) binders-new)))
> +                   (push `(,closedsym ,var-def) binders-new)))

Looks good.
Side note: I don't understand why we `(cons closedsym`, since that
`closedsym` can never appear in another binding (since it's fresh).

[ Version B: ]

> @@ -441,14 +442,16 @@ cconv-convert
>                         (cconv-convert value env extend)))))
>=20=20
>                 (when (and (eq letsym 'let*) (memq var new-extend))
> -                 ;; One of the lambda-lifted vars is shadowed, so add
> -                 ;; a reference to the outside binding and arrange to use
> -                 ;; that reference.
> -                 (let ((var-def (cconv--lifted-arg var env))
> -                       (closedsym (make-symbol (format "closed-%s" var))=
))
> -                   (setq new-env (cconv--remap-llv new-env var closedsym=
))
> -                   (setq new-extend (cons closedsym (remq var new-extend=
)))
> -                   (push `(,closedsym ,var-def) binders-new)))
> +                 ;; One of the lambda-lifted vars is shadowed; if
> +                 ;; necessary, add a reference to the outside binding
> +                 ;; and arrange to use that reference.
> +                 (let* ((lifted-arg (cconv--lifted-arg var env)))
> +                   ;; This means that we may add accessors to ENV and EX=
TEND
> +                   ;; passing them off as variables, but it's close enou=
gh.
> +                   (setq new-env (cconv--remap-llv new-env var lifted-ar=
g))
> +                   (setq new-extend (cons lifted-arg (remq var new-exten=
d)))
> +                   (when (symbolp lifted-arg)
> +                     (push `(,lifted-arg ,var) binders-new))))

Just like I think the `(cons closedsym` is useless in the current (and
in patch A), I think this `(cons lifted-arg` is not needed.

I don't much like this `symbolp` test (which fundamentally seems to
be trying to recover the information about which branch of the `pcase`
we're coming from in `cconv--lifted-arg`).  It at least deserves
a comment explaining why it's doing the right thing.
If we can remove this `symbolp` test recovering info about provenance of
the result of `cconv--lifted-arg` then I think option B is better, but
I prefer otherwise option A.


        Stefan





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 30 Nov 2021 17:02:07 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Nov 30 12:02:07 2021
Received: from localhost ([127.0.0.1]:42275 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ms6W7-0004Gy-82
	for submit <at> debbugs.gnu.org; Tue, 30 Nov 2021 12:02:07 -0500
Received: from mail204c50.megamailservers.eu ([91.136.10.214]:43162
 helo=mail193c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1ms6W4-0004Gl-UX
 for 51982 <at> debbugs.gnu.org; Tue, 30 Nov 2021 12:02:06 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1638291722;
 bh=0seGn+0F4vzzaDd7XFe7H71PayTjUzjB3DvIgFbsOlo=;
 h=From:Subject:Date:In-Reply-To:Cc:To:References:From;
 b=M4XdyEyHwna5fTx1jD3JOVb0C/9SUa/OYoWrSRt+walJRKTYuwnmE7xojV0EbkqNQ
 +t0nMowau8ATCoC6m52EKrJBPotcc7aMMhbWWUnP5OEIoefAZLbxnXvzSINq11JoYN
 9CjQacG2jZD9D1xT4g4l1V+3k0Xdi9J9SuSu+Z5M=
Feedback-ID: mattiase@HIDDEN
Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se
 [83.227.82.185]) (authenticated bits=0)
 by mail193c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AUH1xgq003746; 
 Tue, 30 Nov 2021 17:02:01 +0000
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Message-Id: <B51CEFD1-DFDF-4C78-93AB-254278776E47@HIDDEN>
Content-Type: multipart/mixed;
 boundary="Apple-Mail=_50889DC4-EA40-47C0-8963-0A04145B17E7"
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
Date: Tue, 30 Nov 2021 18:01:59 +0100
In-Reply-To: <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
To: Stefan Monnier <monnier@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
 <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
 <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F20.61A6590A.009D, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=LIkF/La9 c=1 sm=1 tr=0 ts=61a6590a
 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17
 a=M51BFTxLslgA:10 a=iRZporoAAAAA:8 a=fYCMnBSh4KlL48zEYLcA:9
 a=QEXdDO2ut3YA:10 a=QG20O0T1PFPAM2fPWDIA:9 a=B2y7HmGcmWMA:10
 a=ZWWpVlJt-r_wLoX5z1kA:9 a=NOBgFS-JBQ2l-kSd6-zu:22
X-Origin-Country: SE
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)


--Apple-Mail=_50889DC4-EA40-47C0-8963-0A04145B17E7
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

30 nov. 2021 kl. 15.12 skrev Stefan Monnier <monnier@HIDDEN>:

> Can we avoid this duplication by moving that code to a separate =
function?

I extracted a big part of the code into a common function but left the =
free variable access and mutation outside. (Really want to get rid of =
`let*`!)

> These two tests are identical aren't they?

No, they exercise different code paths (let and let*).

>  Also, can we change the
> (setq x x) into something like (setq x (list x x)) and avoid using the
> same `b` value for both `x` vars, so as to catch more potential =
errors?

Yes, thank you, it was an editing mistake. Fixed.

> Looks good (better than patch A).

And here I was prepared to apply patch A since it's slightly more =
conservative and it seems to be a rare problem anyway.
I've now split the patches in a more sensible (and easily reviewed) way: =
the first corresponds to patch A, and the second is the diff to B. Take =
a second look before making up your mind.

> You say "On the other hand, patch B does abuse the cconv data =
structures
> a little (but it works!)" so the code should say something about
> this abuse.  A least I failed to see where the abuse lies.

There are comments and doc strings such as

  EXTEND is a list of variables which might need to be accessed even =
from places
  where they are shadowed, because some part of ENV causes them to be =
used at
  places where they originally did not directly appear.

but with the B patch we put things into `extend` that are not strictly =
variables but (international-get-closed-var N).
Similarly, `env` has entries like (VAR . (apply-partially F ARG1 ARG2 =
..)) where the ARGi are always treated as variables but now they can be =
access forms as well.

I suppose it doesn't matter much. There is an assertion at the very top =
of `cconv-convert` which compares the elements by `eq` but it seems to =
work all right...

Thanks for the review =E2=80=93 new patches attached.


--Apple-Mail=_50889DC4-EA40-47C0-8963-0A04145B17E7
Content-Disposition: attachment;
	filename=0001-Fix-closure-conversion-of-shadowed-captured-lambda-l.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="0001-Fix-closure-conversion-of-shadowed-captured-lambda-l.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=20b56b04ac23f74dddd4648c9f86c8cf7423f70829=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@HIDDEN>=0ADate:=20Mon,=2022=20Nov=202021=2016:56:38=20+0100=0A=
Subject:=20[PATCH=201/2]=20Fix=20closure-conversion=20of=20shadowed=20=
captured=20lambda-lifted=0A=20vars=0A=0A*=20lisp/emacs-lisp/cconv.el=20=
(cconv--lifted-arg):=20New.=0A(cconv-convert):=0ALambda=20lifted=20=
variables=20(ones=20passed=20explicitly=20to=20lambda-lifted=0A=
functions)=20that=20are=20also=20captured=20in=20an=20outer=20closure=20=
and=20shadowed=0Awere=20renamed=20incorrectly.=20=20Fix=20that=20by=20=
providing=20the=20correct=0Adefiniens=20for=20the=20closed-over=20=
variable=20(bug#51982).=0A=0A*=20test/lisp/emacs-lisp/bytecomp-tests.el=20=
(bytecomp-tests--test-cases):=0A*=20test/lisp/emacs-lisp/cconv-tests.el=20=
(cconv-tests--intern-all)=0A(cconv-closure-convert-remap-var):=20Add=20=
tests.=0A---=0A=20lisp/emacs-lisp/cconv.el=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20|=20=2028=20++++-=0A=20=
test/lisp/emacs-lisp/bytecomp-tests.el=20|=20=2041=20+++++++=0A=20=
test/lisp/emacs-lisp/cconv-tests.el=20=20=20=20|=20152=20=
+++++++++++++++++++++++++=0A=203=20files=20changed,=20215=20=
insertions(+),=206=20deletions(-)=0A=0Adiff=20--git=20=
a/lisp/emacs-lisp/cconv.el=20b/lisp/emacs-lisp/cconv.el=0Aindex=20=
03e109f250..9808547b84=20100644=0A---=20a/lisp/emacs-lisp/cconv.el=0A+++=20=
b/lisp/emacs-lisp/cconv.el=0A@@=20-304,6=20+304,22=20@@=20=
cconv--convert-funcbody=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
`(,@(nreverse=20special-forms)=20,@(macroexp-unprogn=20body))))=0A=20=20=20=
=20=20=20=20funcbody)))=0A=20=0A+(defun=20cconv--lifted-arg=20(var=20=
env)=0A+=20=20"The=20argument=20to=20use=20for=20VAR=20in=20=CE=BB-lifted=20=
calls=20according=20to=20ENV."=0A+=20=20(let=20((mapping=20(cdr=20(assq=20=
var=20env))))=0A+=20=20=20=20(pcase-exhaustive=20mapping=0A+=20=20=20=20=20=
=20(`(internal-get-closed-var=20.=20,_)=0A+=20=20=20=20=20=20=20;;=20The=20=
variable=20is=20captured.=0A+=20=20=20=20=20=20=20mapping)=0A+=20=20=20=20=
=20=20(`(car-safe=20(internal-get-closed-var=20.=20,_))=0A+=20=20=20=20=20=
=20=20;;=20The=20variable=20is=20mutably=20captured;=20skip=0A+=20=20=20=20=
=20=20=20;;=20the=20indirection=20step=20because=20the=20variable=20is=0A=
+=20=20=20=20=20=20=20;;=20passed=20"by=20reference"=20to=20the=20=
=CE=BB-lifted=20function.=0A+=20=20=20=20=20=20=20(cadr=20mapping))=0A+=20=
=20=20=20=20=20((or=20'()=20`(car-safe=20,(pred=20symbolp)))=0A+=20=20=20=
=20=20=20=20;;=20The=20variable=20is=20not=20captured;=20use=20the=20=
(shadowed)=20variable=20value.=0A+=20=20=20=20=20=20=20var))))=0A+=0A=20=
(defun=20cconv-convert=20(form=20env=20extend)=0A=20=20=20;;=20This=20=
function=20actually=20rewrites=20the=20tree.=0A=20=20=20"Return=20FORM=20=
with=20all=20its=20lambdas=20changed=20so=20they=20are=20closed.=0A@@=20=
-428,10=20+444,11=20@@=20cconv-convert=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20=
shadowed,=20so=20add=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20;;=20a=20reference=20to=20the=20outside=20binding=20and=20arrange=20=
to=20use=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
that=20reference.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((closedsym=20(make-symbol=20(format=20"closed-%s"=20var))))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((var-def=20=
(cconv--lifted-arg=20var=20env))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(closedsym=20(make-symbol=20(format=20=
"closed-%s"=20var))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20=
closedsym))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20new-extend=20(cons=20closedsym=20(remq=20var=20new-extend)))=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20=
`(,closedsym=20,var)=20binders-new)))=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(push=20`(,closedsym=20,var-def)=20=
binders-new)))=0A=20=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
;;=20We=20push=20the=20element=20after=20redefined=20free=20variables=20=
are=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20processed.=20=20=
This=20is=20important=20to=20avoid=20the=20bug=20when=20free=0A@@=20=
-449,14=20+466,13=20@@=20cconv-convert=0A=20=20=20=20=20=20=20=20=20=20=
;;=20before=20we=20know=20that=20the=20var=20will=20be=20in=20=
`new-extend'=20(bug#24171).=0A=20=20=20=20=20=20=20=20=20=20(dolist=20=
(binder=20binders-new)=0A=20=20=20=20=20=20=20=20=20=20=20=20(when=20=
(memq=20(car-safe=20binder)=20new-extend)=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20shadowed,=20=
so=20add=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20a=20reference=20=
to=20the=20outside=20binding=20and=20arrange=20to=20use=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20=20;;=20that=20reference.=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20=
shadowed.=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((var=20=
(car-safe=20binder))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(var-def=20(cconv--lifted-arg=20var=20env))=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closedsym=20(make-symbol=20=
(format=20"closed-%s"=20var))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20=
closedsym))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20=
new-extend=20(cons=20closedsym=20(remq=20var=20new-extend)))=0A-=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(push=20`(,closedsym=20,var)=20=
binders-new)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20=
`(,closedsym=20,var-def)=20binders-new)))))=0A=20=0A=20=20=20=20=20=20=20=
=20`(,letsym=20,(nreverse=20binders-new)=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20.=20,(mapcar=20(lambda=20(form)=0Adiff=20--git=20=
a/test/lisp/emacs-lisp/bytecomp-tests.el=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0Aindex=20=
816f14a18d..a75a33b2dc=20100644=0A---=20=
a/test/lisp/emacs-lisp/bytecomp-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0A@@=20-643,6=20+643,47=20@@=20=
bytecomp-tests--test-cases=0A=20=0A=20=20=20=20=20(cond)=0A=20=20=20=20=20=
(mapcar=20(lambda=20(x)=20(cond=20((=3D=20x=200))))=20'(0=201))=0A+=0A+=20=
=20=20=20;;=20These=20expressions=20give=20different=20results=20in=20=
lexbind=20and=20dynbind=20modes,=0A+=20=20=20=20;;=20but=20in=20each=20=
the=20compiler=20and=20interpreter=20should=20agree!=0A+=20=20=20=20(let=20=
((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20=
((g=20(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20=
(funcall=20(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20=
(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20(funcall=20=
(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20x)))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20(list=20x=20=
x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20=
((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20(funcall=20=
(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20x)))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20(list=20x=20=
x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20(funcall=20=
(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20x))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(h=20(lambda=20=
()=20(setq=20x=20(list=20x=20x)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=
=20=20=20=20(funcall=20(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20=
(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((g=20=
(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(h=20(lambda=20()=20(setq=20x=20(list=20x=20x)))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20'a))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
g)=20(funcall=20h)))))))=0A+=20=20=20=20=20=20(funcall=20(funcall=20f=20=
'b)))=0A=20=20=20=20=20)=0A=20=20=20"List=20of=20expressions=20for=20=
cross-testing=20interpreted=20and=20compiled=20code.")=0A=20=0Adiff=20=
--git=20a/test/lisp/emacs-lisp/cconv-tests.el=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0Aindex=204290571735..0701892b8c=20=
100644=0A---=20a/test/lisp/emacs-lisp/cconv-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0A@@=20-205,5=20+205,157=20@@=20=
cconv-convert-lambda-lifted=0A=20=20=20=20=20=20=20=20=20=20=20=20nil=20=
99)=0A=20=20=20=20=20=20=20=20=20=20=2042)))=0A=20=0A+(defun=20=
cconv-tests--intern-all=20(x)=0A+=20=20"Intern=20all=20symbols=20in=20=
X."=0A+=20=20(cond=20((symbolp=20x)=20(intern=20(symbol-name=20x)))=0A+=20=
=20=20=20=20=20=20=20((consp=20x)=20(cons=20(cconv-tests--intern-all=20=
(car=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(cconv-tests--intern-all=20(cdr=20x))))=0A+=20=20=20=20=20=
=20=20=20;;=20Assume=20we=20don't=20need=20to=20deal=20with=20vectors=20=
etc.=0A+=20=20=20=20=20=20=20=20(t=20x)))=0A+=0A+(ert-deftest=20=
cconv-closure-convert-remap-var=20()=0A+=20=20;;=20Verify=20that=20we=20=
correctly=20remap=20shadowed=20lambda-lifted=20variables.=0A+=0A+=20=20=
;;=20We=20intern=20all=20symbols=20for=20ease=20of=20comparison;=20this=20=
works=20because=0A+=20=20;;=20the=20`cconv-closure-convert'=20result=20=
should=20contain=20no=20pair=20of=0A+=20=20;;=20distinct=20symbols=20=
having=20the=20same=20name.=0A+=0A+=20=20;;=20Sanity=20check:=20captured=20=
variable,=20no=20lambda-lifting=20or=20shadowing:=0A+=20=20(should=20=
(equal=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20=
(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20#'(lambda=20()=20=
x))))=0A+=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(internal-make-closure=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(internal-get-closed-var=200)))))=0A=
+=0A+=20=20;;=20Basic=20case:=0A+=20=20(should=20(equal=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(let=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f)))))))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20=
#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((x=20'b)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f=20closed-x)))))))=0A+=20=20(should=20=
(equal=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let*=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
f)))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((closed-x=20x)=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
closed-x)))))))=0A+=0A+=20=20;;=20With=20the=20lambda-lifted=20shadowed=20=
variable=20also=20being=20captured:=0A+=20=20(should=20(equal=0A+=20=20=20=
=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((x=20'a)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20closed-x))))))))=0A+=20=
=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20'a))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let*=20((closed-x=20(internal-get-closed-var=200))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(list=20x=20(funcall=20f=20closed-x))))))))=0A+=20=20;;=20With=20=
lambda-lifted=20shadowed=20variable=20also=20being=20mutably=20captured:=0A=
+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20=
'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20(car-safe=20x))))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setcar=20=
(internal-get-closed-var=200)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(car-safe=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((x=20'a)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
closed-x)))))))))=0A+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=
=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20=
'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20(car-safe=20x))))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setcar=20=
(internal-get-closed-var=200)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(car-safe=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let*=20((closed-x=20(internal-get-closed-var=20=
0))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20closed-x)))))))))=0A=
+=20=20;;=20Lambda-lifted=20variable=20that=20isn't=20actually=20=
captured=20where=20it=20is=20shadowed:=0A+=20=20(should=20(equal=0A+=20=20=
=20=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((g=20#'(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(h=20#'(lambda=20()=20(setq=20=
x=20x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=20=
=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((g=20#'(lambda=20(x)=20(car-safe=20x)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(h=20#'(lambda=20(x)=20(setcar=20x=20(car-safe=20x)))))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'b)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(closed-x=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20g=20closed-x)=20(funcall=20h=20=
closed-x))))))))=0A+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=
=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((g=20#'(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(h=20#'(lambda=20()=20(setq=20x=20=
x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let*=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(let=20((g=20#'(lambda=20(x)=20(car-safe=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(h=20#'(lambda=20(x)=20(setcar=20x=20(car-safe=20x)))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((closed-x=20=
x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(list=20x=20(funcall=20g=20closed-x)=20(funcall=20h=20=
closed-x))))))))=0A+=20=20)=0A+=0A=20(provide=20'cconv-tests)=0A=20;;;=20=
cconv-tests.el=20ends=20here=0A--=20=0A2.21.1=20(Apple=20Git-122.3)=0A=0A=

--Apple-Mail=_50889DC4-EA40-47C0-8963-0A04145B17E7
Content-Disposition: attachment;
	filename=0002-Improved-closure-conversion-of-shadowed-captured-lam.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="0002-Improved-closure-conversion-of-shadowed-captured-lam.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=20e93f3f44cc31a47e54c301157ce91f1b4d79e57e=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@HIDDEN>=0ADate:=20Mon,=2022=20Nov=202021=2016:56:38=20+0100=0A=
Subject:=20[PATCH=202/2]=20Improved=20closure-conversion=20of=20shadowed=20=
captured=0A=20lambda-lifted=20vars=0A=0A*=20lisp/emacs-lisp/cconv.el=20=
(cconv-convert):=0AEliminate=20the=20intermediate=20variable=20=
`closed-VAR`=20when=20the=20shadowed=0Avariable=20is=20captured=20in=20=
an=20outer=20closure,=20since=20the=20accessor=20can=20be=0Aused=20=
directly=20(bug#51982).=0A=0A*=20test/lisp/emacs-lisp/cconv-tests.el=20=
(cconv-tests--intern-all)=0A(cconv-closure-convert-remap-var):=20Adapt=20=
tests.=0A---=0A=20lisp/emacs-lisp/cconv.el=20=20=20=20=20=20=20=20=20=20=20=
=20|=2033=20++++++++++++++++-------------=0A=20=
test/lisp/emacs-lisp/cconv-tests.el=20|=2020=20+++++++----------=0A=202=20=
files=20changed,=2026=20insertions(+),=2027=20deletions(-)=0A=0Adiff=20=
--git=20a/lisp/emacs-lisp/cconv.el=20b/lisp/emacs-lisp/cconv.el=0Aindex=20=
9808547b84..a50aab93f2=20100644=0A---=20a/lisp/emacs-lisp/cconv.el=0A+++=20=
b/lisp/emacs-lisp/cconv.el=0A@@=20-317,8=20+317,9=20@@=20=
cconv--lifted-arg=0A=20=20=20=20=20=20=20=20;;=20passed=20"by=20=
reference"=20to=20the=20=CE=BB-lifted=20function.=0A=20=20=20=20=20=20=20=
=20(cadr=20mapping))=0A=20=20=20=20=20=20=20((or=20'()=20`(car-safe=20=
,(pred=20symbolp)))=0A-=20=20=20=20=20=20=20;;=20The=20variable=20is=20=
not=20captured;=20use=20the=20(shadowed)=20variable=20value.=0A-=20=20=20=
=20=20=20=20var))))=0A+=20=20=20=20=20=20=20;;=20The=20variable=20is=20=
not=20captured.=20=20Add=20a=20reference=20to=20the=0A+=20=20=20=20=20=20=
=20;;=20outside=20binding=20and=20arrange=20to=20use=20that=20reference.=0A=
+=20=20=20=20=20=20=20(make-symbol=20(format=20"closed-%s"=20var))))))=0A=
=20=0A=20(defun=20cconv-convert=20(form=20env=20extend)=0A=20=20=20;;=20=
This=20function=20actually=20rewrites=20the=20tree.=0A@@=20-441,14=20=
+442,16=20@@=20cconv-convert=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(cconv-convert=20value=20env=20extend)))))=0A=
=20=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(when=20(and=20(eq=20=
letsym=20'let*)=20(memq=20var=20new-extend))=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20=
shadowed,=20so=20add=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
;;=20a=20reference=20to=20the=20outside=20binding=20and=20arrange=20to=20=
use=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20that=20=
reference.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20=
((var-def=20(cconv--lifted-arg=20var=20env))=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closedsym=20(make-symbol=20=
(format=20"closed-%s"=20var))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20=
closedsym))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20new-extend=20(cons=20closedsym=20(remq=20var=20new-extend)))=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20=
`(,closedsym=20,var-def)=20binders-new)))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20=
shadowed;=20if=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
necessary,=20add=20a=20reference=20to=20the=20outside=20binding=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20and=20arrange=20to=20=
use=20that=20reference.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(let*=20((lifted-arg=20(cconv--lifted-arg=20var=20env)))=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20This=20means=20that=20=
we=20may=20add=20accessors=20to=20ENV=20and=20EXTEND=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20passing=20them=20off=20as=20=
variables,=20but=20it's=20close=20enough.=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20=
var=20lifted-arg))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(setq=20new-extend=20(cons=20lifted-arg=20(remq=20var=20=
new-extend)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(when=20(symbolp=20lifted-arg)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(push=20`(,lifted-arg=20,var)=20binders-new))))=0A=
=20=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20We=20push=20=
the=20element=20after=20redefined=20free=20variables=20are=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20processed.=20=20This=20is=20=
important=20to=20avoid=20the=20bug=20when=20free=0A@@=20-468,11=20=
+471,11=20@@=20cconv-convert=0A=20=20=20=20=20=20=20=20=20=20=20=20(when=20=
(memq=20(car-safe=20binder)=20new-extend)=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20shadowed.=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((var=20(car-safe=20=
binder))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(var-def=20(cconv--lifted-arg=20var=20env))=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(closedsym=20(make-symbol=20(format=20=
"closed-%s"=20var))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20closedsym))=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20new-extend=20(cons=20=
closedsym=20(remq=20var=20new-extend)))=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(push=20`(,closedsym=20,var-def)=20binders-new)))))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lifted-arg=20=
(cconv--lifted-arg=20var=20env)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20=
lifted-arg))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20=
new-extend=20(cons=20lifted-arg=20(remq=20var=20new-extend)))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(when=20(symbolp=20lifted-arg)=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20`(,lifted-arg=20=
,var)=20binders-new))))))=0A=20=0A=20=20=20=20=20=20=20=20`(,letsym=20=
,(nreverse=20binders-new)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20.=20,(mapcar=20(lambda=20(form)=0Adiff=20--git=20=
a/test/lisp/emacs-lisp/cconv-tests.el=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0Aindex=200701892b8c..3bd34e08d3=20=
100644=0A---=20a/test/lisp/emacs-lisp/cconv-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0A@@=20-267,9=20+267,8=20@@=20=
cconv-closure-convert-remap-var=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(internal-make-closure=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20nil=20(x)=20nil=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20x)))=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a)=0A-=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
(internal-get-closed-var=200)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20closed-x))))))))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20=
x=20(funcall=20f=20(internal-get-closed-var=200)))))))))=0A=20=20=20=
(should=20(equal=0A=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-tests--intern-all=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A@@=20-282,9=20+281,8=20@@=20=
cconv-closure-convert-remap-var=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(internal-make-closure=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20nil=20(x)=20nil=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20x)))=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((closed-x=20=
(internal-get-closed-var=200))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(x=20'a))=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
closed-x))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(let*=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(list=20x=20(funcall=20f=20(internal-get-closed-var=20=
0)))))))))=0A=20=20=20;;=20With=20lambda-lifted=20shadowed=20variable=20=
also=20being=20mutably=20captured:=0A=20=20=20(should=20(equal=0A=20=20=20=
=20=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A@@=20-302,9=20=
+300,8=20@@=20cconv-closure-convert-remap-var=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20=
(car-safe=20x))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(setcar=20(internal-get-closed-var=200)=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(car-safe=20(internal-get-closed-var=200)))=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a)=0A-=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
(internal-get-closed-var=200)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
closed-x)))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
(internal-get-closed-var=200))))))))))=0A=20=20=20(should=20(equal=0A=20=20=
=20=20=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20(cconv-closure-convert=0A@@=20-321,9=20+318,8=20@@=20=
cconv-closure-convert-remap-var=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20(car-safe=20x))))=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setcar=20=
(internal-get-closed-var=200)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(car-safe=20=
(internal-get-closed-var=200)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let*=20((closed-x=20(internal-get-closed-var=20=
0))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(x=20'a))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20closed-x)))))))))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(list=20x=20(funcall=20f=20(internal-get-closed-var=20=
0))))))))))=0A=20=20=20;;=20Lambda-lifted=20variable=20that=20isn't=20=
actually=20captured=20where=20it=20is=20shadowed:=0A=20=20=20(should=20=
(equal=0A=20=20=20=20=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A=
--=20=0A2.21.1=20(Apple=20Git-122.3)=0A=0A=

--Apple-Mail=_50889DC4-EA40-47C0-8963-0A04145B17E7--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 30 Nov 2021 14:12:33 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Nov 30 09:12:33 2021
Received: from localhost ([127.0.0.1]:40465 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ms3s1-0004t7-2v
	for submit <at> debbugs.gnu.org; Tue, 30 Nov 2021 09:12:33 -0500
Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:38285)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <monnier@HIDDEN>) id 1ms3ry-0004sr-AU
 for 51982 <at> debbugs.gnu.org; Tue, 30 Nov 2021 09:12:31 -0500
Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1])
 by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 5D5B24413A5;
 Tue, 30 Nov 2021 09:12:24 -0500 (EST)
Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1])
 by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id ECCF8441392;
 Tue, 30 Nov 2021 09:12:21 -0500 (EST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca;
 s=mail; t=1638281541;
 bh=xDNKp6+GvEScxtLHSp3kGfkMcDJ43Eb/8NP2sgODffQ=;
 h=From:To:Cc:Subject:References:Date:In-Reply-To:From;
 b=mQxmbu6yGwiiFr0qVtsgKROD6KaJsLX4NiDPeeDIFs4H50bR7YLdxc/b10xcQLuQC
 ZinjfUSX7pUB6WtcmnNCwTdxx+V4Wo4wNJxyh38a7kFTHuaHIXaHmnQbz4uAcCRpJ7
 LG3NAVFPY/9k/XkRt4W+cmxWXJczY2Qgm1DPU32xTZ1XH4eQvhotpg/dJWdJm43eOT
 1i084c6+Dh7F+mJBtxRp1cu5VgKi6vAdEla60Rinolp2uXtZ40Mf55KIBxkifno5VX
 iT3UGbvE5FCxT9vzNXeyty3MpTbu+7Td6R1xmb6IhKzAPyCxHkES9hyeQxEv4Myusn
 SrUX3+5V6XBaQ==
Received: from pastel (unknown [216.154.30.173])
 by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id BB087120124;
 Tue, 30 Nov 2021 09:12:21 -0500 (EST)
From: Stefan Monnier <monnier@HIDDEN>
To: Mattias =?windows-1252?Q?Engdeg=E5rd?= <mattiase@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in
 byte-compiled nested lambdas
Message-ID: <jwvfsrdkaf8.fsf-monnier+emacs@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
 <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
Date: Tue, 30 Nov 2021 09:12:20 -0500
In-Reply-To: <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN> ("Mattias
 =?windows-1252?Q?Engdeg=E5rd=22's?= message of "Mon, 22 Nov 2021 18:35:18
 +0100")
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-SPAM-INFO: Spam detection results:  0
 ALL_TRUSTED                -1 Passed through trusted hosts only via SMTP
 AWL -0.062 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily valid
 DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature
 DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's
 domain
X-SPAM-LEVEL: 
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Sorry 'bout the delay, and thanks Mattias for finding the bug and the fix.

> @@ -428,10 +428,26 @@ cconv-convert
>                   ;; One of the lambda-lifted vars is shadowed, so add
>                   ;; a reference to the outside binding and arrange to use
>                   ;; that reference.
> -                 (let ((closedsym (make-symbol (format "closed-%s" var))=
))
> -                   (setq new-env (cconv--remap-llv new-env var closedsym=
))
> -                   (setq new-extend (cons closedsym (remq var new-extend=
)))
> -                   (push `(,closedsym ,var) binders-new)))
> +                 (let* ((mapping (cdr (assq var env)))
> +                        (var-def
> +                         (pcase-exhaustive mapping
> +                           (`(internal-get-closed-var . ,_)
> +                            ;; The variable is captured.
> +                            mapping)
> +                           (`(car-safe (internal-get-closed-var . ,_))
> +                            ;; The variable is mutably captured; skip
> +                            ;; the indirection step because the variable=
 is
> +                            ;; passed "by rerefence" to the =CE=BB-lifte=
d function.
> +                            (cadr mapping))
> +                           ((or '() `(car-safe ,(pred symbolp)))
> +                            ;; The variable is not captured.  Add a
> +                            ;; reference to the outside binding and arra=
nge
> +                            ;; to use that reference.
> +                            var))))
> +                   (let ((closedsym (make-symbol (format "closed-%s" var=
))))
> +                     (setq new-env (cconv--remap-llv new-env var closeds=
ym))
> +                     (setq new-extend (cons closedsym (remq var new-exte=
nd)))
> +                     (push `(,closedsym ,var-def) binders-new))))
>=20=20
>                 ;; We push the element after redefined free variables are
>                 ;; processed.  This is important to avoid the bug when fr=
ee
> @@ -449,14 +465,28 @@ cconv-convert
>           ;; before we know that the var will be in `new-extend' (bug#241=
71).
>           (dolist (binder binders-new)
>             (when (memq (car-safe binder) new-extend)
> -             ;; One of the lambda-lifted vars is shadowed, so add
> -             ;; a reference to the outside binding and arrange to use
> -             ;; that reference.
> +             ;; One of the lambda-lifted vars is shadowed.
>               (let* ((var (car-safe binder))
> -                    (closedsym (make-symbol (format "closed-%s" var))))
> -               (setq new-env (cconv--remap-llv new-env var closedsym))
> -               (setq new-extend (cons closedsym (remq var new-extend)))
> -               (push `(,closedsym ,var) binders-new)))))
> +                    (mapping (cdr (assq var env)))
> +                    (var-def
> +                     (pcase-exhaustive mapping
> +                       (`(internal-get-closed-var . ,_)
> +                        ;; The variable is captured.
> +                        mapping)
> +                       (`(car-safe (internal-get-closed-var . ,_))
> +                        ;; The variable is mutably captured; skip
> +                        ;; the indirection step because the variable is
> +                        ;; passed "by rerefence" to the =CE=BB-lifted fu=
nction.
> +                        (cadr mapping))
> +                       ((or '() `(car-safe ,(pred symbolp)))
> +                        ;; The variable is not captured.  Add a
> +                        ;; reference to the outside binding and
> +                        ;; arrange to use that reference.
> +                        var))))
> +               (let ((closedsym (make-symbol (format "closed-%s" var))))
> +                 (setq new-env (cconv--remap-llv new-env var closedsym))
> +                 (setq new-extend (cons closedsym (remq var new-extend)))
> +                 (push `(,closedsym ,var-def) binders-new))))))

Can we avoid this duplication by moving that code to a separate function?

> +    (let ((f (lambda (x)
> +               (let ((g (lambda () x))
> +                     (h (lambda () (setq x x))))
> +                 (let ((x 'b))
> +                   (list x (funcall g) (funcall h)))))))
> +      (funcall (funcall f 'b)))
> +    (let ((f (lambda (x)
> +               (let ((g (lambda () x))
> +                     (h (lambda () (setq x x))))
> +                 (let* ((x 'b))
> +                   (list x (funcall g) (funcall h)))))))
> +      (funcall (funcall f 'b)))

These two tests are identical aren't they?  Also, can we change the
(setq x x) into something like (setq x (list x x)) and avoid using the
same `b` value for both `x` vars, so as to catch more potential errors?

> @@ -428,10 +428,27 @@ cconv-convert
>                   ;; One of the lambda-lifted vars is shadowed, so add
>                   ;; a reference to the outside binding and arrange to use
>                   ;; that reference.
> -                 (let ((closedsym (make-symbol (format "closed-%s" var))=
))
> -                   (setq new-env (cconv--remap-llv new-env var closedsym=
))
> -                   (setq new-extend (cons closedsym (remq var new-extend=
)))
> -                   (push `(,closedsym ,var) binders-new)))
> +                 (let* ((mapping (cdr (assq var env)))
> +                        (remap-to
> +                         (pcase-exhaustive mapping
> +                           (`(internal-get-closed-var . ,_)
> +                            ;; The variable is captured; remap.
> +                            mapping)
> +                           (`(car-safe (internal-get-closed-var . ,_))
> +                            ;; The variable is mutably captured; remap, =
but skip
> +                            ;; the indirection step because the variable=
 is
> +                            ;; passed "by rerefence" to the =CE=BB-lifte=
d function.
> +                            (cadr mapping))
> +                           ((or '() `(car-safe ,(pred symbolp)))
> +                            ;; The variable is not captured.  Add a
> +                            ;; reference to the outside binding and arra=
nge
> +                            ;; to use that reference.
> +                            (let ((closedsym
> +                                   (make-symbol (format "closed-%s" var)=
)))
> +                              (push `(,closedsym ,var) binders-new)
> +                              closedsym)))))
> +                   (setq new-env (cconv--remap-llv new-env var remap-to))
> +                   (setq new-extend (cons remap-to (remq var new-extend)=
))))
>=20=20
>                 ;; We push the element after redefined free variables are
>                 ;; processed.  This is important to avoid the bug when fr=
ee

Looks good (better than patch A).

You say "On the other hand, patch B does abuse the cconv data structures
a little (but it works!)" so the code should say something about
this abuse.  A least I failed to see where the abuse lies.

> @@ -449,14 +466,29 @@ cconv-convert
>           ;; before we know that the var will be in `new-extend' (bug#241=
71).
>           (dolist (binder binders-new)
>             (when (memq (car-safe binder) new-extend)
> -             ;; One of the lambda-lifted vars is shadowed, so add
> -             ;; a reference to the outside binding and arrange to use
> -             ;; that reference.
> +             ;; One of the lambda-lifted vars is shadowed.
>               (let* ((var (car-safe binder))
> -                    (closedsym (make-symbol (format "closed-%s" var))))
> -               (setq new-env (cconv--remap-llv new-env var closedsym))
> -               (setq new-extend (cons closedsym (remq var new-extend)))
> -               (push `(,closedsym ,var) binders-new)))))
> +                    (mapping (cdr (assq var env)))
> +                    (remap-to
> +                     (pcase-exhaustive mapping
> +                       (`(internal-get-closed-var . ,_)
> +                        ;; The variable is captured; remap.
> +                        mapping)
> +                       (`(car-safe (internal-get-closed-var . ,_))
> +                        ;; The variable is mutably captured; remap, but =
skip
> +                        ;; the indirection step because the variable is
> +                        ;; passed "by rerefence" to the =CE=BB-lifted fu=
nction.
> +                        (cadr mapping))
> +                       ((or '() `(car-safe ,(pred symbolp)))
> +                        ;; The variable is not captured.  Add a
> +                        ;; reference to the outside binding and arrange
> +                        ;; to use that reference.
> +                        (let ((closedsym
> +                               (make-symbol (format "closed-%s" var))))
> +                          (push `(,closedsym ,var) binders-new)
> +                          closedsym)))))
> +               (setq new-env (cconv--remap-llv new-env var remap-to))
> +               (setq new-extend (cons remap-to (remq var new-extend)))))=
))

Same comment as before about the code duplication.


        Stefan





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.
Added tag(s) patch. Request was from Mattias EngdegÄrd <mattiase@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 22 Nov 2021 17:35:40 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Nov 22 12:35:39 2021
Received: from localhost ([127.0.0.1]:48998 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1mpDEB-00073o-41
	for submit <at> debbugs.gnu.org; Mon, 22 Nov 2021 12:35:39 -0500
Received: from mail1454c50.megamailservers.eu ([91.136.14.54]:53358
 helo=mail266c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1mpDE4-00073P-Dd
 for 51982 <at> debbugs.gnu.org; Mon, 22 Nov 2021 12:35:37 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1637602525;
 bh=BJK0aWQ8BvaejY4gEf7WHVpdlzhTD/FnaTzAXOrpFmA=;
 h=From:Subject:Date:In-Reply-To:Cc:To:References:From;
 b=lEiFPKOqdkYZEE5oJr3qopYesr8b+cAo1CC3rH0J8wGF6t4NMUdmUAt7Ey+aNQUGB
 QwepPz7V2oq3VzzgZGxfWLGVRWJlFc0IGf97hB1tlmz3FLhapQ4sXTTujEi8tJygiS
 K59C6G+KNfJGiHSiOHOq06cPZjiDO4kIChS2yup0=
Feedback-ID: mattiase@HIDDEN
Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se
 [83.227.82.185]) (authenticated bits=0)
 by mail266c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AMHZIuf013513; 
 Mon, 22 Nov 2021 17:35:20 +0000
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Message-Id: <ED0329E9-B3EF-4F2A-AD7A-329B9A382D9E@HIDDEN>
Content-Type: multipart/mixed;
 boundary="Apple-Mail=_6202F8C8-FAA9-429A-9E5E-24A6D73097EA"
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
Date: Mon, 22 Nov 2021 18:35:18 +0100
In-Reply-To: <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
To: Michael Heerdegen <michael_heerdegen@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN> <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F18.619BD4DD.0026, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=E5KuGYRl c=1 sm=1 tr=0 ts=619bd4dd
 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17
 a=M51BFTxLslgA:10 a=5hr3uwvhae-bEsuNmpYA:9 a=CjuIK1q_8ugA:10
 a=Hj0ZHtO1rmNFOb7b9sgA:9 a=B2y7HmGcmWMA:10 a=5hiNXCo7YkXxgPKWgXEA:9
X-Origin-Country: SE
X-Spam-Score: 0.4 (/)
X-Debbugs-Envelope-To: 51982
Cc: Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org,
 Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)


--Apple-Mail=_6202F8C8-FAA9-429A-9E5E-24A6D73097EA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

> I just found a case where it doesn't work. A repaired patch will =
arrive soon (we hope).

Not one but two patches for your enjoyment, representing two alternative =
solutions. Patch A is an extension of the original proposal and is =
simpler but perhaps less performant; patch B is messier but may result =
in better code.

To connect to the previous example, cconv transforms the function

(defun f (x)
  (lambda ()
    (let ((f (lambda () x)))
      (let ((x 'a))
        (list x (funcall f))))))

with patch A into

(defun f (x)
  (internal-make-closure
   nil (x) nil
   (let ((f (lambda (x) x)))
     (let ((x 'a)
           (closed-x (internal-get-closed-var 0)))
       (list x (funcall f closed-x))))))

and with patch B into

(defun f (x)
  (internal-make-closure
   nil (x) nil
   (let ((f (lambda (x) x)))
     (let ((x 'a))
       (list x (funcall f (internal-get-closed-var 0)))))))

This looks like a wash but the optimiser isn't able to elide that =
superfluous closed-x variable yet, and in Paul's original example the =
captured variable is only used in one conditional branch which makes it =
a loss to bind it up-front whereas it's very cheap to materialise at the =
call site (a single constant-pushing byte op).

On the other hand, patch B does abuse the cconv data structures a little =
(but it works!). We'll see if Stefan can stomach it.

(This reminds me: we should probably declare internal-get-closed-var as =
pure and error-free, even though it's not even an actual function.)


--Apple-Mail=_6202F8C8-FAA9-429A-9E5E-24A6D73097EA
Content-Disposition: attachment;
	filename=bug51982-A.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="bug51982-A.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=20e3b306c9748c8738ed9086fb81562031865dffda=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@HIDDEN>=0ADate:=20Mon,=2022=20Nov=202021=2016:56:38=20+0100=0A=
Subject:=20[PATCH]=20Fix=20closure-conversion=20of=20shadowed=20captured=20=
lambda-lifted=0A=20vars=0A=0A*=20lisp/emacs-lisp/cconv.el=20=
(cconv-convert):=0ALambda=20lifted=20variables=20(ones=20passed=20=
explicitly=20to=20lambda-lifted=0Afunctions)=20that=20are=20also=20=
captured=20in=20an=20outer=20closure=20and=20shadowed=0Awere=20renamed=20=
incorrectly.=20=20Fix=20that=20by=20providing=20the=20correct=0A=
definiens=20for=20the=20closed-over=20variable=20(bug#51982).=0A=0A*=20=
test/lisp/emacs-lisp/bytecomp-tests.el=20(bytecomp-tests--test-cases):=0A=
*=20test/lisp/emacs-lisp/cconv-tests.el=20(cconv-tests--intern-all)=0A=
(cconv-closure-convert-remap-var):=20Add=20tests.=0A---=0A=20=
lisp/emacs-lisp/cconv.el=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=
=2052=20+++++++--=0A=20test/lisp/emacs-lisp/bytecomp-tests.el=20|=20=20=
41=20+++++++=0A=20test/lisp/emacs-lisp/cconv-tests.el=20=20=20=20|=20152=20=
+++++++++++++++++++++++++=0A=203=20files=20changed,=20234=20=
insertions(+),=2011=20deletions(-)=0A=0Adiff=20--git=20=
a/lisp/emacs-lisp/cconv.el=20b/lisp/emacs-lisp/cconv.el=0Aindex=20=
03e109f250..34663937cc=20100644=0A---=20a/lisp/emacs-lisp/cconv.el=0A+++=20=
b/lisp/emacs-lisp/cconv.el=0A@@=20-428,10=20+428,26=20@@=20cconv-convert=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20One=20of=20=
the=20lambda-lifted=20vars=20is=20shadowed,=20so=20add=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20a=20reference=20to=20the=20=
outside=20binding=20and=20arrange=20to=20use=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20;;=20that=20reference.=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(let=20((closedsym=20(make-symbol=20=
(format=20"closed-%s"=20var))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20=
closedsym))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20new-extend=20(cons=20closedsym=20(remq=20var=20new-extend)))=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20=
`(,closedsym=20,var)=20binders-new)))=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(let*=20((mapping=20(cdr=20(assq=20var=20env)))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(var-def=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(pcase-exhaustive=20mapping=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(`(internal-get-closed-var=20.=20,_)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20variable=20=
is=20captured.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20mapping)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(`(car-safe=20=
(internal-get-closed-var=20.=20,_))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20variable=20is=20=
mutably=20captured;=20skip=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20the=20indirection=20step=20=
because=20the=20variable=20is=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20passed=20"by=20rerefence"=20=
to=20the=20=CE=BB-lifted=20function.=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cadr=20mapping))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20((or=20'()=20`(car-safe=20,(pred=20symbolp)))=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20=
variable=20is=20not=20captured.=20=20Add=20a=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20reference=20=
to=20the=20outside=20binding=20and=20arrange=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20to=20use=20=
that=20reference.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20var))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((closedsym=20(make-symbol=20(format=20=
"closed-%s"=20var))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20=
closedsym))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(setq=20new-extend=20(cons=20closedsym=20(remq=20var=20new-extend)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20=
`(,closedsym=20,var-def)=20binders-new))))=0A=20=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20;;=20We=20push=20the=20element=20after=20=
redefined=20free=20variables=20are=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20;;=20processed.=20=20This=20is=20important=20to=20avoid=20=
the=20bug=20when=20free=0A@@=20-449,14=20+465,28=20@@=20cconv-convert=0A=20=
=20=20=20=20=20=20=20=20=20;;=20before=20we=20know=20that=20the=20var=20=
will=20be=20in=20`new-extend'=20(bug#24171).=0A=20=20=20=20=20=20=20=20=20=
=20(dolist=20(binder=20binders-new)=0A=20=20=20=20=20=20=20=20=20=20=20=20=
(when=20(memq=20(car-safe=20binder)=20new-extend)=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20=
shadowed,=20so=20add=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20a=20=
reference=20to=20the=20outside=20binding=20and=20arrange=20to=20use=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20that=20reference.=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20=
is=20shadowed.=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((var=20=
(car-safe=20binder))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(closedsym=20(make-symbol=20(format=20"closed-%s"=20var))))=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20new-env=20=
(cconv--remap-llv=20new-env=20var=20closedsym))=0A-=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(setq=20new-extend=20(cons=20closedsym=20(remq=20=
var=20new-extend)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(push=20`(,closedsym=20,var)=20binders-new)))))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(mapping=20(cdr=20(assq=20var=20=
env)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(var-def=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(pcase-exhaustive=20mapping=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(`(internal-get-closed-var=20.=20,_)=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
The=20variable=20is=20captured.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20mapping)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(`(car-safe=20=
(internal-get-closed-var=20.=20,_))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20variable=20is=20mutably=20=
captured;=20skip=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20;;=20the=20indirection=20step=20because=20the=20=
variable=20is=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20;;=20passed=20"by=20rerefence"=20to=20the=20=CE=BB-lifted=20=
function.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(cadr=20mapping))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20((or=20'()=20`(car-safe=20,(pred=20symbolp)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
;;=20The=20variable=20is=20not=20captured.=20=20Add=20a=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20reference=20=
to=20the=20outside=20binding=20and=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20arrange=20to=20use=20that=20=
reference.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20var))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20=
((closedsym=20(make-symbol=20(format=20"closed-%s"=20var))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20new-env=20=
(cconv--remap-llv=20new-env=20var=20closedsym))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(setq=20new-extend=20(cons=20closedsym=20=
(remq=20var=20new-extend)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(push=20`(,closedsym=20,var-def)=20binders-new))))))=0A=20=0A=20=
=20=20=20=20=20=20=20`(,letsym=20,(nreverse=20binders-new)=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20,(mapcar=20(lambda=20=
(form)=0Adiff=20--git=20a/test/lisp/emacs-lisp/bytecomp-tests.el=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0Aindex=20=
dbc0aa3db4..c427cd7536=20100644=0A---=20=
a/test/lisp/emacs-lisp/bytecomp-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0A@@=20-643,6=20+643,47=20@@=20=
bytecomp-tests--test-cases=0A=20=0A=20=20=20=20=20(cond)=0A=20=20=20=20=20=
(mapcar=20(lambda=20(x)=20(cond=20((=3D=20x=200))))=20'(0=201))=0A+=0A+=20=
=20=20=20;;=20These=20expressions=20give=20different=20results=20in=20=
lexbind=20and=20dynbind=20modes,=0A+=20=20=20=20;;=20but=20in=20each=20=
the=20compiler=20and=20interpreter=20should=20agree!=0A+=20=20=20=20(let=20=
((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20=
((g=20(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20=
(funcall=20(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20=
(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20(funcall=20=
(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20x)))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20=
(funcall=20g))))))))=0A+=20=20=20=20=20=20(funcall=20(funcall=20f=20=
'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((g=20(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20'a))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
g))))))))=0A+=20=20=20=20=20=20(funcall=20(funcall=20f=20'b)))=0A+=20=20=20=
=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(let=20((g=20(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(h=20(lambda=20()=20(setq=20x=20x))))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'b))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
g)=20(funcall=20h)))))))=0A+=20=20=20=20=20=20(funcall=20(funcall=20f=20=
'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20x))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(h=20(lambda=20()=20(setq=20=
x=20x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=20=20=20=
(funcall=20(funcall=20f=20'b)))=0A=20=20=20=20=20)=0A=20=20=20"List=20of=20=
expressions=20for=20cross-testing=20interpreted=20and=20compiled=20=
code.")=0A=20=0Adiff=20--git=20a/test/lisp/emacs-lisp/cconv-tests.el=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0Aindex=204290571735..0701892b8c=20=
100644=0A---=20a/test/lisp/emacs-lisp/cconv-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0A@@=20-205,5=20+205,157=20@@=20=
cconv-convert-lambda-lifted=0A=20=20=20=20=20=20=20=20=20=20=20=20nil=20=
99)=0A=20=20=20=20=20=20=20=20=20=20=2042)))=0A=20=0A+(defun=20=
cconv-tests--intern-all=20(x)=0A+=20=20"Intern=20all=20symbols=20in=20=
X."=0A+=20=20(cond=20((symbolp=20x)=20(intern=20(symbol-name=20x)))=0A+=20=
=20=20=20=20=20=20=20((consp=20x)=20(cons=20(cconv-tests--intern-all=20=
(car=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(cconv-tests--intern-all=20(cdr=20x))))=0A+=20=20=20=20=20=
=20=20=20;;=20Assume=20we=20don't=20need=20to=20deal=20with=20vectors=20=
etc.=0A+=20=20=20=20=20=20=20=20(t=20x)))=0A+=0A+(ert-deftest=20=
cconv-closure-convert-remap-var=20()=0A+=20=20;;=20Verify=20that=20we=20=
correctly=20remap=20shadowed=20lambda-lifted=20variables.=0A+=0A+=20=20=
;;=20We=20intern=20all=20symbols=20for=20ease=20of=20comparison;=20this=20=
works=20because=0A+=20=20;;=20the=20`cconv-closure-convert'=20result=20=
should=20contain=20no=20pair=20of=0A+=20=20;;=20distinct=20symbols=20=
having=20the=20same=20name.=0A+=0A+=20=20;;=20Sanity=20check:=20captured=20=
variable,=20no=20lambda-lifting=20or=20shadowing:=0A+=20=20(should=20=
(equal=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20=
(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20#'(lambda=20()=20=
x))))=0A+=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(internal-make-closure=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(internal-get-closed-var=200)))))=0A=
+=0A+=20=20;;=20Basic=20case:=0A+=20=20(should=20(equal=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(let=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f)))))))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20=
#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((x=20'b)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f=20closed-x)))))))=0A+=20=20(should=20=
(equal=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let*=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
f)))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((closed-x=20x)=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
closed-x)))))))=0A+=0A+=20=20;;=20With=20the=20lambda-lifted=20shadowed=20=
variable=20also=20being=20captured:=0A+=20=20(should=20(equal=0A+=20=20=20=
=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((x=20'a)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20closed-x))))))))=0A+=20=
=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20'a))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let*=20((closed-x=20(internal-get-closed-var=200))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(list=20x=20(funcall=20f=20closed-x))))))))=0A+=20=20;;=20With=20=
lambda-lifted=20shadowed=20variable=20also=20being=20mutably=20captured:=0A=
+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20=
'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20(car-safe=20x))))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setcar=20=
(internal-get-closed-var=200)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(car-safe=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((x=20'a)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
closed-x)))))))))=0A+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=
=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20=
'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20(car-safe=20x))))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setcar=20=
(internal-get-closed-var=200)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(car-safe=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let*=20((closed-x=20(internal-get-closed-var=20=
0))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20closed-x)))))))))=0A=
+=20=20;;=20Lambda-lifted=20variable=20that=20isn't=20actually=20=
captured=20where=20it=20is=20shadowed:=0A+=20=20(should=20(equal=0A+=20=20=
=20=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((g=20#'(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(h=20#'(lambda=20()=20(setq=20=
x=20x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=20=
=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((g=20#'(lambda=20(x)=20(car-safe=20x)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(h=20#'(lambda=20(x)=20(setcar=20x=20(car-safe=20x)))))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'b)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(closed-x=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20g=20closed-x)=20(funcall=20h=20=
closed-x))))))))=0A+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=
=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((g=20#'(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(h=20#'(lambda=20()=20(setq=20x=20=
x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let*=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(let=20((g=20#'(lambda=20(x)=20(car-safe=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(h=20#'(lambda=20(x)=20(setcar=20x=20(car-safe=20x)))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((closed-x=20=
x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(list=20x=20(funcall=20g=20closed-x)=20(funcall=20h=20=
closed-x))))))))=0A+=20=20)=0A+=0A=20(provide=20'cconv-tests)=0A=20;;;=20=
cconv-tests.el=20ends=20here=0A--=20=0A2.21.1=20(Apple=20Git-122.3)=0A=0A=

--Apple-Mail=_6202F8C8-FAA9-429A-9E5E-24A6D73097EA
Content-Disposition: attachment;
	filename=bug51982-B.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="bug51982-B.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=203bcad5e4c21f94cc91a397685848f1887ac21207=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@HIDDEN>=0ADate:=20Mon,=2022=20Nov=202021=2016:56:38=20+0100=0A=
Subject:=20[PATCH]=20Fix=20closure-conversion=20of=20shadowed=20captured=20=
lambda-lifted=0A=20vars=0A=0A*=20lisp/emacs-lisp/cconv.el=20=
(cconv-convert):=0ALambda=20lifted=20variables=20(ones=20passed=20=
explicitly=20to=20lambda-lifted=0Afunctions)=20that=20are=20also=20=
captured=20in=20an=20outer=20closure=20and=20shadowed=0Awere=20renamed=20=
incorrectly.=20=20Fix=20that=20by=20dropping=20the=20renaming=0Asince=20=
it's=20not=20needed=20for=20captured=20variables=20(bug#51982).=0A=0A*=20=
test/lisp/emacs-lisp/bytecomp-tests.el=20(bytecomp-tests--test-cases):=0A=
*=20test/lisp/emacs-lisp/cconv-tests.el=20(cconv-tests--intern-all)=0A=
(cconv-closure-convert-remap-var):=20Add=20tests.=0A---=0A=20=
lisp/emacs-lisp/cconv.el=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=
=2054=20+++++++--=0A=20test/lisp/emacs-lisp/bytecomp-tests.el=20|=20=20=
41=20+++++++=0A=20test/lisp/emacs-lisp/cconv-tests.el=20=20=20=20|=20148=20=
+++++++++++++++++++++++++=0A=203=20files=20changed,=20232=20=
insertions(+),=2011=20deletions(-)=0A=0Adiff=20--git=20=
a/lisp/emacs-lisp/cconv.el=20b/lisp/emacs-lisp/cconv.el=0Aindex=20=
03e109f250..8989bd412f=20100644=0A---=20a/lisp/emacs-lisp/cconv.el=0A+++=20=
b/lisp/emacs-lisp/cconv.el=0A@@=20-428,10=20+428,27=20@@=20cconv-convert=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20One=20of=20=
the=20lambda-lifted=20vars=20is=20shadowed,=20so=20add=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20a=20reference=20to=20the=20=
outside=20binding=20and=20arrange=20to=20use=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20;;=20that=20reference.=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(let=20((closedsym=20(make-symbol=20=
(format=20"closed-%s"=20var))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(setq=20new-env=20(cconv--remap-llv=20new-env=20var=20=
closedsym))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20new-extend=20(cons=20closedsym=20(remq=20var=20new-extend)))=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20=
`(,closedsym=20,var)=20binders-new)))=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(let*=20((mapping=20(cdr=20(assq=20var=20env)))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(remap-to=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(pcase-exhaustive=20mapping=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(`(internal-get-closed-var=20.=20,_)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20variable=20=
is=20captured;=20remap.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20mapping)=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(`(car-safe=20=
(internal-get-closed-var=20.=20,_))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20variable=20is=20=
mutably=20captured;=20remap,=20but=20skip=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20the=20=
indirection=20step=20because=20the=20variable=20is=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
passed=20"by=20rerefence"=20to=20the=20=CE=BB-lifted=20function.=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(cadr=20mapping))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20((or=20'()=20`(car-safe=20,(pred=20=
symbolp)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20;;=20The=20variable=20is=20not=20captured.=20=20=
Add=20a=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20reference=20to=20the=20outside=20binding=20and=20=
arrange=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20to=20use=20that=20reference.=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((closedsym=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(make-symbol=20=
(format=20"closed-%s"=20var))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20`(,closedsym=20=
,var)=20binders-new)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20closedsym)))))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20new-env=20=
(cconv--remap-llv=20new-env=20var=20remap-to))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setq=20new-extend=20(cons=20remap-to=20=
(remq=20var=20new-extend)))))=0A=20=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20;;=20We=20push=20the=20element=20after=20redefined=20free=20=
variables=20are=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
processed.=20=20This=20is=20important=20to=20avoid=20the=20bug=20when=20=
free=0A@@=20-449,14=20+466,29=20@@=20cconv-convert=0A=20=20=20=20=20=20=20=
=20=20=20;;=20before=20we=20know=20that=20the=20var=20will=20be=20in=20=
`new-extend'=20(bug#24171).=0A=20=20=20=20=20=20=20=20=20=20(dolist=20=
(binder=20binders-new)=0A=20=20=20=20=20=20=20=20=20=20=20=20(when=20=
(memq=20(car-safe=20binder)=20new-extend)=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20shadowed,=20=
so=20add=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20a=20reference=20=
to=20the=20outside=20binding=20and=20arrange=20to=20use=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20=20;;=20that=20reference.=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20;;=20One=20of=20the=20lambda-lifted=20vars=20is=20=
shadowed.=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((var=20=
(car-safe=20binder))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(closedsym=20(make-symbol=20(format=20"closed-%s"=20var))))=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20new-env=20=
(cconv--remap-llv=20new-env=20var=20closedsym))=0A-=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(setq=20new-extend=20(cons=20closedsym=20(remq=20=
var=20new-extend)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(push=20`(,closedsym=20,var)=20binders-new)))))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(mapping=20(cdr=20(assq=20var=20=
env)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(remap-to=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(pcase-exhaustive=20mapping=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(`(internal-get-closed-var=20.=20,_)=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
The=20variable=20is=20captured;=20remap.=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20mapping)=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(`(car-safe=20=
(internal-get-closed-var=20.=20,_))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20variable=20is=20mutably=20=
captured;=20remap,=20but=20skip=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20;;=20the=20indirection=20step=20because=20=
the=20variable=20is=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20passed=20"by=20rerefence"=20to=20the=20=
=CE=BB-lifted=20function.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(cadr=20mapping))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20((or=20'()=20`(car-safe=20=
,(pred=20symbolp)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20The=20variable=20is=20not=20captured.=20=20Add=20=
a=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20;;=20reference=20to=20the=20outside=20binding=20and=20arrange=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
to=20use=20that=20reference.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(let=20((closedsym=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(make-symbol=20(format=20"closed-%s"=20var))))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20=
`(,closedsym=20,var)=20binders-new)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20closedsym)))))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(setq=20new-env=20(cconv--remap-llv=20=
new-env=20var=20remap-to))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20new-extend=20(cons=20remap-to=20(remq=20var=20new-extend)))))))=0A=
=20=0A=20=20=20=20=20=20=20=20`(,letsym=20,(nreverse=20binders-new)=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20,(mapcar=20=
(lambda=20(form)=0Adiff=20--git=20=
a/test/lisp/emacs-lisp/bytecomp-tests.el=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0Aindex=20=
dbc0aa3db4..c427cd7536=20100644=0A---=20=
a/test/lisp/emacs-lisp/bytecomp-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0A@@=20-643,6=20+643,47=20@@=20=
bytecomp-tests--test-cases=0A=20=0A=20=20=20=20=20(cond)=0A=20=20=20=20=20=
(mapcar=20(lambda=20(x)=20(cond=20((=3D=20x=200))))=20'(0=201))=0A+=0A+=20=
=20=20=20;;=20These=20expressions=20give=20different=20results=20in=20=
lexbind=20and=20dynbind=20modes,=0A+=20=20=20=20;;=20but=20in=20each=20=
the=20compiler=20and=20interpreter=20should=20agree!=0A+=20=20=20=20(let=20=
((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20=
((g=20(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20=
(funcall=20(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20=
(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(list=20x=20(funcall=20g))))))))=0A+=20=20=20=20=20=20(funcall=20=
(funcall=20f=20'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20x)))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20=
(funcall=20g))))))))=0A+=20=20=20=20=20=20(funcall=20(funcall=20f=20=
'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((g=20(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20'a))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
g))))))))=0A+=20=20=20=20=20=20(funcall=20(funcall=20f=20'b)))=0A+=20=20=20=
=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(let=20((g=20(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(h=20(lambda=20()=20(setq=20x=20x))))=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'b))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
g)=20(funcall=20h)))))))=0A+=20=20=20=20=20=20(funcall=20(funcall=20f=20=
'b)))=0A+=20=20=20=20(let=20((f=20(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((g=20(lambda=20()=20x))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(h=20(lambda=20()=20(setq=20=
x=20x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=20=20=20=
(funcall=20(funcall=20f=20'b)))=0A=20=20=20=20=20)=0A=20=20=20"List=20of=20=
expressions=20for=20cross-testing=20interpreted=20and=20compiled=20=
code.")=0A=20=0Adiff=20--git=20a/test/lisp/emacs-lisp/cconv-tests.el=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0Aindex=204290571735..3bd34e08d3=20=
100644=0A---=20a/test/lisp/emacs-lisp/cconv-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/cconv-tests.el=0A@@=20-205,5=20+205,153=20@@=20=
cconv-convert-lambda-lifted=0A=20=20=20=20=20=20=20=20=20=20=20=20nil=20=
99)=0A=20=20=20=20=20=20=20=20=20=20=2042)))=0A=20=0A+(defun=20=
cconv-tests--intern-all=20(x)=0A+=20=20"Intern=20all=20symbols=20in=20=
X."=0A+=20=20(cond=20((symbolp=20x)=20(intern=20(symbol-name=20x)))=0A+=20=
=20=20=20=20=20=20=20((consp=20x)=20(cons=20(cconv-tests--intern-all=20=
(car=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(cconv-tests--intern-all=20(cdr=20x))))=0A+=20=20=20=20=20=
=20=20=20;;=20Assume=20we=20don't=20need=20to=20deal=20with=20vectors=20=
etc.=0A+=20=20=20=20=20=20=20=20(t=20x)))=0A+=0A+(ert-deftest=20=
cconv-closure-convert-remap-var=20()=0A+=20=20;;=20Verify=20that=20we=20=
correctly=20remap=20shadowed=20lambda-lifted=20variables.=0A+=0A+=20=20=
;;=20We=20intern=20all=20symbols=20for=20ease=20of=20comparison;=20this=20=
works=20because=0A+=20=20;;=20the=20`cconv-closure-convert'=20result=20=
should=20contain=20no=20pair=20of=0A+=20=20;;=20distinct=20symbols=20=
having=20the=20same=20name.=0A+=0A+=20=20;;=20Sanity=20check:=20captured=20=
variable,=20no=20lambda-lifting=20or=20shadowing:=0A+=20=20(should=20=
(equal=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20=
(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20#'(lambda=20()=20=
x))))=0A+=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(internal-make-closure=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(internal-get-closed-var=200)))))=0A=
+=0A+=20=20;;=20Basic=20case:=0A+=20=20(should=20(equal=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(let=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f)))))))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20=
#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((x=20'b)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(closed-x=20=
x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f=20closed-x)))))))=0A+=20=20(should=20=
(equal=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let*=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20=
f)))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((closed-x=20x)=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
closed-x)))))))=0A+=0A+=20=20;;=20With=20the=20lambda-lifted=20shadowed=20=
variable=20also=20being=20captured:=0A+=20=20(should=20(equal=0A+=20=20=20=
=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'a))=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
(internal-get-closed-var=200)))))))))=0A+=20=20(should=20(equal=0A+=20=20=
=20=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20'a))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((f=20#'(lambda=20(x)=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let*=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
(internal-get-closed-var=200)))))))))=0A+=20=20;;=20With=20lambda-lifted=20=
shadowed=20variable=20also=20being=20mutably=20captured:=0A+=20=20=
(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=20=20=
(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20=
'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=20=20=20=20=20=
=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(internal-make-closure=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20(car-safe=20x))))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setcar=20=
(internal-get-closed-var=200)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(car-safe=20=
(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f=20=
(internal-get-closed-var=200))))))))))=0A+=20=20(should=20(equal=0A+=20=20=
=20=20=20=20=20=20=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20#'(lambda=20()=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(let=20((f=20#'(lambda=20()=20x)))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20x)=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let*=20((x=20'a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(list=20x=20(funcall=20f))))))))=0A+=20=20=20=20=
=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(internal-make-closure=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20nil=20(x)=20nil=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((f=20#'(lambda=20(x)=20=
(car-safe=20x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(setcar=20(internal-get-closed-var=200)=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(car-safe=20(internal-get-closed-var=200)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((x=20'a))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20=
(funcall=20f=20(internal-get-closed-var=200))))))))))=0A+=20=20;;=20=
Lambda-lifted=20variable=20that=20isn't=20actually=20captured=20where=20=
it=20is=20shadowed:=0A+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=
=20=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((g=20#'(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(h=20#'(lambda=20()=20(setq=20x=20=
x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=20=
=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((g=20#'(lambda=20(x)=20(car-safe=20x)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(h=20#'(lambda=20(x)=20(setcar=20x=20(car-safe=20x)))))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((x=20'b)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(closed-x=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(list=20x=20(funcall=20g=20closed-x)=20(funcall=20h=20=
closed-x))))))))=0A+=20=20(should=20(equal=0A+=20=20=20=20=20=20=20=20=20=
=20=20(cconv-tests--intern-all=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
(cconv-closure-convert=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((g=20#'(lambda=20()=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(h=20#'(lambda=20()=20(setq=20x=20=
x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let*=20((x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(list=20x=20(funcall=20g)=20(funcall=20h)))))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20'#'(lambda=20(x)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(let=20((x=20(list=20x)))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(let=20((g=20#'(lambda=20(x)=20(car-safe=20=
x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(h=20#'(lambda=20(x)=20(setcar=20x=20(car-safe=20x)))))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((closed-x=20=
x)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(x=20'b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(list=20x=20(funcall=20g=20closed-x)=20(funcall=20h=20=
closed-x))))))))=0A+=20=20)=0A+=0A=20(provide=20'cconv-tests)=0A=20;;;=20=
cconv-tests.el=20ends=20here=0A--=20=0A2.21.1=20(Apple=20Git-122.3)=0A=0A=

--Apple-Mail=_6202F8C8-FAA9-429A-9E5E-24A6D73097EA--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 22 Nov 2021 13:56:42 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Nov 22 08:56:42 2021
Received: from localhost ([127.0.0.1]:47274 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1mp9oH-0006xi-UR
	for submit <at> debbugs.gnu.org; Mon, 22 Nov 2021 08:56:42 -0500
Received: from mail1440c50.megamailservers.eu ([91.136.14.40]:58568
 helo=mail264c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1mp9oE-0006xB-4F
 for 51982 <at> debbugs.gnu.org; Mon, 22 Nov 2021 08:56:41 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1637589390;
 bh=K843LqoSxJqC+bC/f4x07gaxa7h20gZ0DoPWhF5MuOo=;
 h=Subject:From:In-Reply-To:Date:Cc:References:To:From;
 b=B3ZT5Vtsl0xKN9N54eG/QZ7MgWO/JWsn6X8dvVv+24Rf2x88xkjDBL0WYZpNe1hND
 Ydg8rREjnh29XPKhPAXqJNPCVqAwJ77qxtF5UPpKlKQbWiaV1My7WkrjXq72pXzZ63
 F9nHVWOxx5QbCOGoAYcYyWjKGfpDqRgmbrIA79fI=
Feedback-ID: mattiase@HIDDEN
Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se
 [83.227.82.185]) (authenticated bits=0)
 by mail264c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AMDuSvC026707; 
 Mon, 22 Nov 2021 13:56:29 +0000
Content-Type: text/plain;
	charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
In-Reply-To: <877dd0bi17.fsf@HIDDEN>
Date: Mon, 22 Nov 2021 14:56:27 +0100
Content-Transfer-Encoding: quoted-printable
Message-Id: <CBD8F94A-ACD8-4540-AF1F-7FB9D8F01B0B@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
 <877dd0bi17.fsf@HIDDEN>
To: Michael Heerdegen <michael_heerdegen@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F1B.619BA18E.0085, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=LMcF/La9 c=1 sm=1 tr=0 ts=619ba18e
 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17
 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=eELQBNv3VbfQu21TQYYA:9
 a=CjuIK1q_8ugA:10
X-Origin-Country: SE
X-Spam-Score: 1.4 (+)
X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org",
 has NOT identified this incoming email as spam.  The original
 message has been attached to this so you can view it or label
 similar future email.  If you have any questions, see
 the administrator of that system for details.
 Content preview: 22 nov. 2021 kl. 11.29 skrev Michael Heerdegen
 <michael_heerdegen@HIDDEN>:
 > Would it help if I rebuild Emacs including the patch to look if > everything
 is fine? Thank you, but you might just as well save that effort for later
 because I just found a case where it doesn't work. A repaired patch will
 arrive soon (we hope). Sorry! 
 Content analysis details:   (1.4 points, 10.0 required)
 pts rule name              description
 ---- ---------------------- --------------------------------------------------
 0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record
 1.0 SPF_SOFTFAIL           SPF: sender does not match SPF record (softfail)
 0.4 KHOP_HELO_FCRDNS       Relay HELO differs from its IP's reverse DNS
X-Debbugs-Envelope-To: 51982
Cc: Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org,
 Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

22 nov. 2021 kl. 11.29 skrev Michael Heerdegen =
<michael_heerdegen@HIDDEN>:

> Would it help if I rebuild Emacs including the patch to look if
> everything is fine?

Thank you, but you might just as well save that effort for later because =
I just found a case where it doesn't work. A repaired patch will arrive =
soon (we hope). Sorry!

> [BTW, how can I tell git-am to not barf about an overlong commit =
message
> and just use the patch?]

The current technological level of mankind is not yet advanced enough =
for such hyper-problems. Our best brains have struggled with it for =
decades to no avail.





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 22 Nov 2021 10:29:45 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Nov 22 05:29:45 2021
Received: from localhost ([127.0.0.1]:47023 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1mp6Zt-0000y1-J8
	for submit <at> debbugs.gnu.org; Mon, 22 Nov 2021 05:29:45 -0500
Received: from mout.web.de ([212.227.17.12]:37481)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <michael_heerdegen@HIDDEN>) id 1mp6Zo-0000xm-U3
 for 51982 <at> debbugs.gnu.org; Mon, 22 Nov 2021 05:29:35 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de;
 s=dbaedf251592; t=1637576950;
 bh=5sv9gVq7QIS1G363oBm5x05OOc8WJycizcEo0l0FEQk=;
 h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To;
 b=f2z+a4s+HPu+dItJTj/2O0mh18v3OoH1t5PB8ihP10odmse4blKSjkpQgXanccwP+
 YL0qabZ2KadgcDldSht3gOwRAEiopHZFxG6dfPcK8bp6ELVAtR59mIdVjTNpJexKuq
 Xkby4h2SxExvM+1Jarm1sUA0n0RnmgtRrhFSm3qE=
X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9
Received: from drachen.dragon ([92.208.225.87]) by smtp.web.de (mrweb105
 [213.165.67.124]) with ESMTPSA (Nemesis) id 1M7epr-1mjKLA3r5h-007y8e; Mon, 22
 Nov 2021 11:29:09 +0100
From: Michael Heerdegen <michael_heerdegen@HIDDEN>
To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in
 byte-compiled nested lambdas
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
Date: Mon, 22 Nov 2021 11:29:08 +0100
In-Reply-To: <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN> ("Mattias
 =?utf-8?Q?Engdeg=C3=A5rd=22's?= message of "Sun, 21 Nov 2021 10:59:15
 +0100")
Message-ID: <877dd0bi17.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Provags-ID: V03:K1:X7zdTrPaR3ZOrzBr6bD21hbYpY+VtOCj2QaY5FCyH8ZVjJUT8rx
 dVn2OLZ1nnXB2ZQ7xGF2q5/YTHNNdchy2BfhGYDDzHH5N0JDkn5LMWO8PEJDfxe1dZ2MTQZ
 p/Rk2hyog39qTOaDIxW/F8gc7fQOxLuCPpxt0FZP63bg4yY+lPKVTDQ5SSffd9oCKZFyauC
 cme0lFz+3mbINnZreF+Tg==
X-Spam-Flag: NO
X-UI-Out-Filterresults: notjunk:1;V03:K0:Y7SabSJ19Ng=:orHVDMHax58+Q9bUDIKDWW
 txjcv45UPpY0GkvT0rhC3HyHfRlhbSbt1onErFSZ5qrdfEVdfZ9mNvuQE54d+wOExHxxo3Lep
 twoi2t68Rh2+9DptCPUmLdF4Aw4+eq4AD9yQEpuhsvqE+4+cjODUL5RsonkSf1qL3KUOEgTTR
 28XfoDWobTUDE3LWLG/7DEkLLGkxRVExkpedrMv9S9H5GySc87xQXTgtwLpPTOtvztiQScByB
 UZ3QJU8EaODMMPN0sD4TDPURO5TQkYR7qd58YZ0ccL/qn7y2k720GworvGx+DFjChaVzq5Wfj
 ylTZFakhaaM2s8+3ayoarNlxiGiIQK+on2/zq85Zy48bIVGa9Z6fRyiTY26LjorpCidDzNDgy
 kixBP3gRYQkz92ci3X70kxiRbUnvmhoP8hpMTEgGe2MXtEyRgPcinWXaubTucvOyPthHd07rn
 YwiZs3Pb/qb4J4PlkDsEs3QfxlIExRb7f/up0ob1cp0ICqJo3Y11kdXJ17TNex2OVuZzmveLG
 rueDlFWkjvUasKRL95j2Juh64W1+TFviUyijU8cj2IW/HOYRQ6tLO9eH56d6TXjI2w3y92I9L
 kZs7pus27KoRMNoSDTt49yI71aDJdAosXV9y+I/m61CYYT8OJJW5Ev3y9QzQ8QVLSVkPrb51H
 NwHIkaCqsUkawrnQRVmdXRu5rhDEi4Bvy7jezUplW2BuuJwSbJXqfCs1oxmYNoCyQfCqUGWKJ
 I2qniTwR7TNOF1GvcarUbnbDldYTb3fH/XSVyiq54nV5gdTCch3qHJwql89qOd+2EaFpVwjpt
 FmXXXKpy27B0w24mwmwxBOsXk2Tivb0cMmDo+2uAXfgmrQ9YBsmoRzHb7OJTexLPwVvJ4D7Pa
 NDFTqCoDoubN5d24kCqdp/8YyrgQNLVyQnK/bHzlanHT0svbZbtpBeiPU5Gi6DGPalc5H74/g
 yZIO6aJXDU2AIHqHMQcOhri/MVNQwaL/znTW7WNRv+LQYTLkCqG3rAoRbuNTj6oYR/PG7OvBX
 x99RIXj+zJu+XNs5BpNQV7jUjuI0BYbAqMAhxiv3tazJYuM6Tq73rsLUmwW7HP7T0zHz6gzwR
 dU8+AZH4UE4uVE=
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 51982
Cc: Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org,
 Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Mattias Engdeg=C3=A5rd <mattiase@HIDDEN> writes:

> I need to take another good look at the code to make sure the change
> is correct (more eyes on it would be appreciated).

Would it help if I rebuild Emacs including the patch to look if
everything is fine?

[BTW, how can I tell git-am to not barf about an overlong commit message
and just use the patch?]

Thanks,

Michael.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 21 Nov 2021 09:59:29 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Nov 21 04:59:29 2021
Received: from localhost ([127.0.0.1]:44263 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1mojdB-0001uy-Bj
	for submit <at> debbugs.gnu.org; Sun, 21 Nov 2021 04:59:29 -0500
Received: from mail1469c50.megamailservers.eu ([91.136.14.69]:49570
 helo=mail102c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1mojd8-0001uc-EQ
 for 51982 <at> debbugs.gnu.org; Sun, 21 Nov 2021 04:59:28 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1637488758;
 bh=q1l8jKhOV3xDgWeAc2bqx0SGfFYbq+6S/fvRt21tBOg=;
 h=Subject:From:In-Reply-To:Date:Cc:References:To:From;
 b=Iqq3oWPSd0OLk+s2S4y0whjK4GiDnvwo8223j5IiAD/rwXZc01npDu/ajak5OGvYF
 A7XWZJ3X/n5ZR1+iXzUhozNBQjBlzVFxnC3W7OI62xmOhhmM75IxTNjI8W/9elxy4g
 xE3dDCLvHIwz30hdJz4+fB3m60cacUQic5r/BZUM=
Feedback-ID: mattiase@HIDDEN
Received: from [192.168.0.4] (c188-150-171-71.bredband.tele2.se
 [188.150.171.71]) (authenticated bits=0)
 by mail102c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AL9xG6q005184; 
 Sun, 21 Nov 2021 09:59:17 +0000
Content-Type: text/plain;
	charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
In-Reply-To: <87wnl23pnd.fsf@HIDDEN>
Date: Sun, 21 Nov 2021 10:59:15 +0100
Content-Transfer-Encoding: quoted-printable
Message-Id: <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <87wnl23pnd.fsf@HIDDEN>
To: Michael Heerdegen <michael_heerdegen@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F23.619A1876.0060, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=Pr3w0yA3 c=1 sm=1 tr=0 ts=619a1876
 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17
 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=NivrlyhRsm14kqCvc6QA:9
 a=CjuIK1q_8ugA:10
X-Origin-Country: SE
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 51982
Cc: Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org,
 Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

21 nov. 2021 kl. 08.59 skrev Michael Heerdegen =
<michael_heerdegen@HIDDEN>:

> If arbitrary fixes would be allowed at any point of the development =
cycle
> the result would be worse than what we have now.  It's also a quite
> common policy.

Yes, but it does cause some inconvenience in a project with Emacs's =
geological release pace. It is difficult to defend an inability to =
rapidly release an updated version when a serious bug has been found.

Now, regarding the actual bug. Consider the function

1 (defun f (x)
2   (lambda ()
3     (let ((g (lambda () x)))
4       (let ((x 'a))
5         (list x (funcall g))))))

First of all, the variable x is free in the function starting in line 2, =
so that function is converted to a closure capturing that variable =
explicitly.

Next, the function bound to g will be lambda-lifted; ie, converted to =
(lambda (x) x) which means that the call to g in line 5 must be amended =
to include the value of x. However, we can't just change (funcall g) to =
(funcall g x) because x is shadowed by the binding in 4, so a new =
variable is introduced for this purpose.

The result after cconv is essentially (without the fix):

1 (defun f (x)
2   (internal-make-closure nil (x) nil
3     (let ((g (lambda (x) x)))
4       (let ((x 'a)
5             (closed-x x))
6         (list x (funcall g closed-x))))))

But x is not the right expression for closed-x, because it is a captured =
variable. The patch fixes this:

1 (defun f (x)
2   (internal-make-closure nil (x) nil
3     (let ((g (lambda (x) x)))
4       (let ((x 'a)
5             (closed-x (internal-get-closed-var 0)))
6         (list x (funcall g closed-x))))))

As I mentioned previously, it would be probably be better to elide =
closed-x entirely and produce

1 (defun f (x)
2   (internal-make-closure nil (x) nil
3     (let ((g (lambda (x) x)))
4       (let ((x 'a))
5         (list x (funcall g (internal-get-closed-var 0)))))))

In other words, the bug occurs when a variable is captured, =
lambda-lifted, and shadowed.
I need to take another good look at the code to make sure the change is =
correct (more eyes on it would be appreciated).





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 21 Nov 2021 07:59:54 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Nov 21 02:59:54 2021
Received: from localhost ([127.0.0.1]:44058 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1mohlR-0002dz-Qk
	for submit <at> debbugs.gnu.org; Sun, 21 Nov 2021 02:59:53 -0500
Received: from mout.web.de ([212.227.15.14]:52195)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <michael_heerdegen@HIDDEN>) id 1mohlP-0002dd-La
 for 51982 <at> debbugs.gnu.org; Sun, 21 Nov 2021 02:59:52 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de;
 s=dbaedf251592; t=1637481576;
 bh=p7ICLr99zqdyOzYcXW6Z0r/b75+ES8sGHnZWseuXYKA=;
 h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To;
 b=MfJTdsI10gmkTU32DmbLem+nfeKNMynTgi6FJv4vR/0fcQCS0200H9xpSr/9SUkVX
 O671AN0ONZl35s0KzoK0RENiEBCd/ifiRBucpIugLYsqZCvugUv+mis2agQ5GCWDAP
 tlO2yAp248qns2e2NvS5QuuYlVQA14wHShAIAdrs=
X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9
Received: from drachen.dragon ([92.208.225.87]) by smtp.web.de (mrweb005
 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MHEXc-1mt3LE2rIG-00DSMn; Sun, 21
 Nov 2021 08:59:36 +0100
From: Michael Heerdegen <michael_heerdegen@HIDDEN>
To: Paul Pogonyshev <pogonyshev@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in
 byte-compiled nested lambdas
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
Date: Sun, 21 Nov 2021 08:59:34 +0100
In-Reply-To: <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 (Paul Pogonyshev's message of "Sat, 20 Nov 2021 18:22:43 +0100")
Message-ID: <87wnl23pnd.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain
X-Provags-ID: V03:K1:RtNWCUfRkpsh620ub0qsnoSMa9yKoV6i+abkl//JAhcxnlb6iD0
 N2dJKgkzsUF+hItvGknbwsGvYUZR5b9MuuqDrSbI5IuXCxi7AlOwlg3KjeuuIT0hT77wrYV
 nbmKDrtwvhMYPCbDVO3NIoNWMucm/B/el5SOWe6Nr/iTJ6mKf5SRcSHu8740SwZjEZi7Mcd
 CivAaMI2jXwhWuY8nQplg==
X-Spam-Flag: NO
X-UI-Out-Filterresults: notjunk:1;V03:K0:P0jPzRplDKQ=:KlZzVb/gMvFxXuAmMxJKJt
 1dQ4D1OzrcV3+JYj67PpjEDOR37zqosoznsYv7ZR/thoUfXVGKP07MI7BiiJOjpwsEPE1Lb+a
 9U2vP5Plhsq5Tn6SpZ/mBTXx+NROJt3GifEnqW++3M1917xF+0mjv8EBx5nOyI48W61EHpUL3
 jPIAylXKdef6qEWHEBiejT5/AacjY0j2DqIe5OtmcQ3rGMQp0r9DIPZH4305poyybADKdSpGf
 Ae+Vk+GPp2VQb9DPfRM0AUnYnuJfxMvLakk7NPgA+PVKE5wQzsqWywc23U3aCFt2bUp6cv4n2
 gl3yHpy4rPx+GsKHGumju+uLopRjDVVsmftfPIiYggPq3dd3Whgyl/SYKgXrdbjgU2CBjBS8k
 yEHFbI7urhXTPfBTC49cwMu2KrhlNNv1uLGC1y5Cy9ys32mZX8sNX5B7Z+0WreJgaCSq0eL54
 FqvSvQ+0IXAra17+kB4y9oRcq4EdAK20gq+LJusSgmhiTPyPLYklcnI8brq1mtsfwaYj9RKnn
 ffwP489/di5aqxCeRCPo3mvya7eZx4pMrwjv47sijKVoCDLyha0zC2b2x/hXnfI2DbYf0OIiV
 D5pK8Js3IZTU73r2+T0ISJkrVdzsVgg8Ql/c+d2S2eP3/9UOBEoZHWopeAWuMNXCkXpXLY5W/
 cUm1bgV6nXLOLIZR+7gqe5u/Ed/qrfM04mvCCreDcXHftPCAhVD/i/dzugfkodMLfQAw51NEO
 RpkurHe/cSsvZgE97KWcH8aWwg0vGYAa9Og12pCRLg6QIaooEEbT4ctdqPIJO4tcz+ohpczpu
 XZpin/H0EdhRa91Hgc3gOxlNgqoKdPhV1HvCoKLX+IXQiAGjHdtm2gNElBWZZaQKhZHNKAthw
 EtBowpzt4YsoctcymPncn6vQbMdPlpRRCZ0F5MGn03lieUPWXT9w+isQXvz8AM7erWQiDwEUk
 E47L+TmAXJQ3b/V+HH8AcvtmE1mFya19GTLz7fz8yEB/QcN0lyCqAUQXSnpE8RIQfs92pQYUp
 8XnQRSTqbFrA5PN2WmQ1H151hAYcXa5lD0Ltm7BJ4ckAdzHgRAnbvKw9HqdVDUab+7BFh2Y5d
 /poa+JFkrglaMs=
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 51982
Cc: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= <mattiase@HIDDEN>,
 Stefan Monnier <monnier@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

Paul Pogonyshev <pogonyshev@HIDDEN> writes:

> > you cannot count on an eventual fix to be back-ported to Emacs 28
>
> Uh, it's not even released yet. Are the stabilization rules so strict
> that even a *fix* cannot go in?

Yes - only fixes of regressions introduced by the same release are
allowed at the moment.

I totally understand your anger, but such rules are useful.  If
arbitrary fixes would be allowed at any point of the development cycle
the result would be worse than what we have now.  It's also a quite
common policy.  Yes, it sucks, but it is necessary nonetheless.

Michael.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 20:53:22 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 20 15:53:22 2021
Received: from localhost ([127.0.0.1]:43744 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moXMQ-0007DW-65
	for submit <at> debbugs.gnu.org; Sat, 20 Nov 2021 15:53:22 -0500
Received: from mail-ed1-f54.google.com ([209.85.208.54]:37678)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pogonyshev@HIDDEN>) id 1moXMM-0007DD-Gp
 for 51982 <at> debbugs.gnu.org; Sat, 20 Nov 2021 15:53:20 -0500
Received: by mail-ed1-f54.google.com with SMTP id e3so58150129edu.4
 for <51982 <at> debbugs.gnu.org>; Sat, 20 Nov 2021 12:53:18 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=qS9uOutmtDQBuN8AIb5J4n7iTsA+fgSz5BvxzDXlAHo=;
 b=CCnbH36cpZ2fyb+R47kJ9PeL4cTITWMrpyyIfqkv19UV1rs1uH7S3hoRk5WaNmcNYX
 btvPb451xk/6vLKyOLvmYkFyrv/+ue891n/tG1/4tbLbm6V04u52X049xd9GAreTQnvC
 dOOkBTPxblThZ8NN+HCMn3Rc7X0Olcl50NHLAKc8EpxZZIkBeMb18miJfl2BGTM4o/uZ
 gURxK3l37TY+HHHzhstvjdKA7uyFHqQcJDCqCdUJ09+zEkXZz/w3I+qIuDMkmicKPpKn
 hredGQBOJXH1TOgBliZb7BtHCgDLJcv/6aYg1iKxmu4wRMhxL1f/3nbiX9nSaqOnas3t
 vC9w==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=qS9uOutmtDQBuN8AIb5J4n7iTsA+fgSz5BvxzDXlAHo=;
 b=1WUUgBAh5sJhOXKms0DQy6ebVTQfdcyekba9V/TnTrJ6yBM6zeolB4DCqOm3iFrX5o
 wpe0QUKWuqL2Fpl2TsM3k/A6CXpSwTGLMrDVY19MD/+augkW/iT1+yOQrFJpddaiv4gn
 hIVixGoV6s2dkUV6YB848VKdJxDzoSbbsIFNTYvPJgW6ioAswy+hy5Y1qnZjk7sEpfgH
 W2kyx+jVu6hPbccHN1sQ6izO1vvTtiDnASJkBWwG2hTXdKxzIzGWRd9wcgAF3MbPF47c
 ZmyrpdFOLOlWGGl4F4MROFH1/4RS2E5aB4+QXh0arsLublF7WGOGI5lZWdvELfIX3FJA
 lt6w==
X-Gm-Message-State: AOAM532e3ueBH0Z+FYeZJ7UYVm4BJUmpj71qlT2GM1Uh8cph299XSST0
 K6BgYpM3kf9om94sI+raU2PcUFJ/mxt9pkDAww==
X-Google-Smtp-Source: ABdhPJwUnP4M1V8s7eA8ttpDr4BzV5vu4kwsprWlDukm8QKWwwWp75LUTz+Dg5PNoYp8Iaexvbej+Ul3Jq9l4pG0ISw=
X-Received: by 2002:a05:6402:5208:: with SMTP id
 s8mr42727721edd.394.1637441592459; 
 Sat, 20 Nov 2021 12:53:12 -0800 (PST)
MIME-Version: 1.0
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
 <DCFA122D-7C44-4DE3-9523-BF5D7D877D13@HIDDEN>
In-Reply-To: <DCFA122D-7C44-4DE3-9523-BF5D7D877D13@HIDDEN>
From: Paul Pogonyshev <pogonyshev@HIDDEN>
Date: Sat, 20 Nov 2021 21:53:01 +0100
Message-ID: <CAG7BpapXtk-W-nwH-Wcd2USZmcwFRPgGTTnZV6XYpS0=L=1qiw@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
To: =?UTF-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Content-Type: multipart/alternative; boundary="00000000000075852505d13e9494"
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Stefan Monnier <monnier@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--00000000000075852505d13e9494
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Thanks for the fix. I'm sure in 2025 it will be released.

On Sat, 20 Nov 2021 at 19:34, Mattias Engdeg=C3=A5rd <mattiase@HIDDEN> wro=
te:

> 20 nov. 2021 kl. 18.22 skrev Paul Pogonyshev <pogonyshev@HIDDEN>:
>
> > > you cannot count on an eventual fix to be back-ported to Emacs 28
> >
> > Uh, it's not even released yet. Are the stabilization rules so strict
> that even a *fix* cannot go in? Unless it is going to be a rewrite of hal=
f
> the file...
>
> Sorry, I'd love to have it in 28 but I don't make the rules.
>
> Meanwhile, here's a lightly tested attempt at a fix. I'm not very
> satisfied by it because it forces an up-front access of a captured
> variable; I'd rather sink it to each application of the =CE=BB-lifted fun=
ction.
>
>

--00000000000075852505d13e9494
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thanks for the fix. I&#39;m sure in 2025 it will be releas=
ed.</div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_att=
r">On Sat, 20 Nov 2021 at 19:34, Mattias Engdeg=C3=A5rd &lt;<a href=3D"mail=
to:mattiase@HIDDEN">mattiase@HIDDEN</a>&gt; wrote:<br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex">20 nov. 2021 kl. 18.22 skrev Paul Pogo=
nyshev &lt;<a href=3D"mailto:pogonyshev@HIDDEN" target=3D"_blank">pogony=
shev@HIDDEN</a>&gt;:<br>
<br>
&gt; &gt; you cannot count on an eventual fix to be back-ported to Emacs 28=
<br>
&gt; <br>
&gt; Uh, it&#39;s not even released yet. Are the stabilization rules so str=
ict that even a *fix* cannot go in? Unless it is going to be a rewrite of h=
alf the file...<br>
<br>
Sorry, I&#39;d love to have it in 28 but I don&#39;t make the rules.<br>
<br>
Meanwhile, here&#39;s a lightly tested attempt at a fix. I&#39;m not very s=
atisfied by it because it forces an up-front access of a captured variable;=
 I&#39;d rather sink it to each application of the =CE=BB-lifted function.<=
br>
<br>
</blockquote></div>

--00000000000075852505d13e9494--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 18:34:16 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 20 13:34:16 2021
Received: from localhost ([127.0.0.1]:43660 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moVBn-0002VD-QE
	for submit <at> debbugs.gnu.org; Sat, 20 Nov 2021 13:34:16 -0500
Received: from mail71c50.megamailservers.eu ([91.136.10.81]:53646
 helo=mail92c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1moVBi-0002Uu-73
 for 51982 <at> debbugs.gnu.org; Sat, 20 Nov 2021 13:34:14 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1637433246;
 bh=3ZOdRkoVHZelMCoDxIpcjEAtXrn2GU1yyXUZWLS1Dzs=;
 h=From:Subject:Date:In-Reply-To:Cc:To:References:From;
 b=XikoX4eQBxs1u/I3CVzRYLpnzDDY7ejVXzPiQeFaOHhJVQewvkgooj2Rts7K9UBFR
 1b31dXy0rUGmcX5DfM/wUtK0sBk1PlwBAfOB7TA2MbcBMHbVqlwn2t6uZvjxJ7XXam
 Qg5QMXz0QDFQWdpjIAF5f3EekM+RBufFYjrKllrQ=
Feedback-ID: mattiase@HIDDEN
Received: from [192.168.0.4] (c188-150-171-71.bredband.tele2.se
 [188.150.171.71]) (authenticated bits=0)
 by mail92c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AKIY3XD031696; 
 Sat, 20 Nov 2021 18:34:05 +0000
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Message-Id: <DCFA122D-7C44-4DE3-9523-BF5D7D877D13@HIDDEN>
Content-Type: multipart/mixed;
 boundary="Apple-Mail=_D7447F0A-66F7-4083-8BF3-8B7D56A60FC3"
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
Date: Sat, 20 Nov 2021 19:34:03 +0100
In-Reply-To: <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
To: Paul Pogonyshev <pogonyshev@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
 <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F1C.61993F9E.004E, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=Y72bDjSN c=1 sm=1 tr=0 ts=61993f9e
 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17
 a=M51BFTxLslgA:10 a=pGLkceISAAAA:8 a=qeIFS-pKyf6qnnE2i3MA:9
 a=QEXdDO2ut3YA:10 a=yO2wDlikK09HlSVJ6-MA:9 a=De_Ol2h6w80A:10
X-Origin-Country: SE
X-Spam-Score: 0.4 (/)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Stefan Monnier <monnier@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)


--Apple-Mail=_D7447F0A-66F7-4083-8BF3-8B7D56A60FC3
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

20 nov. 2021 kl. 18.22 skrev Paul Pogonyshev <pogonyshev@HIDDEN>:

> > you cannot count on an eventual fix to be back-ported to Emacs 28
>=20
> Uh, it's not even released yet. Are the stabilization rules so strict =
that even a *fix* cannot go in? Unless it is going to be a rewrite of =
half the file...

Sorry, I'd love to have it in 28 but I don't make the rules.

Meanwhile, here's a lightly tested attempt at a fix. I'm not very =
satisfied by it because it forces an up-front access of a captured =
variable; I'd rather sink it to each application of the =CE=BB-lifted =
function.


--Apple-Mail=_D7447F0A-66F7-4083-8BF3-8B7D56A60FC3
Content-Disposition: attachment;
	filename=cconv-bug51982.diff
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="cconv-bug51982.diff"
Content-Transfer-Encoding: 7bit

diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 03e109f250..17deb8b90a 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -431,7 +431,8 @@ cconv-convert
                  (let ((closedsym (make-symbol (format "closed-%s" var))))
                    (setq new-env (cconv--remap-llv new-env var closedsym))
                    (setq new-extend (cons closedsym (remq var new-extend)))
-                   (push `(,closedsym ,var) binders-new)))
+                   (let ((var-def (or (cdr (assq var env)) var)))
+                     (push `(,closedsym ,var-def) binders-new))))
 
                ;; We push the element after redefined free variables are
                ;; processed.  This is important to avoid the bug when free
@@ -456,7 +457,8 @@ cconv-convert
                     (closedsym (make-symbol (format "closed-%s" var))))
                (setq new-env (cconv--remap-llv new-env var closedsym))
                (setq new-extend (cons closedsym (remq var new-extend)))
-               (push `(,closedsym ,var) binders-new)))))
+               (let ((var-def (or (cdr (assq var env)) var)))
+                 (push `(,closedsym ,var-def) binders-new))))))
 
        `(,letsym ,(nreverse binders-new)
                  . ,(mapcar (lambda (form)
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index dbc0aa3db4..ed596ef3b4 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -643,6 +643,15 @@ bytecomp-tests--test-cases
 
     (cond)
     (mapcar (lambda (x) (cond ((= x 0)))) '(0 1))
+
+    ;; This gives different results in lexbind and dynbind modes,
+    ;; but in each the compiler and interpreter should agree!
+    (let ((f (lambda (x)
+               (lambda ()
+                 (let ((g (lambda () x)))
+                   (let ((x 'a))
+                     (list x (funcall g))))))))
+      (funcall (funcall f 'b)))
     )
   "List of expressions for cross-testing interpreted and compiled code.")
 
diff --git a/test/lisp/emacs-lisp/cconv-tests.el b/test/lisp/emacs-lisp/cconv-tests.el
index 4290571735..b6a789fcfe 100644
--- a/test/lisp/emacs-lisp/cconv-tests.el
+++ b/test/lisp/emacs-lisp/cconv-tests.el
@@ -205,5 +205,88 @@ cconv-convert-lambda-lifted
            nil 99)
           42)))
 
+(defun cconv-tests--intern-all (x)
+  "Intern all symbols in X."
+  (cond ((symbolp x) (intern (symbol-name x)))
+        ((consp x) (cons (cconv-tests--intern-all (car x))
+                         (cconv-tests--intern-all (cdr x))))
+        ;; Assume we don't need to deal with vectors etc.
+        (t x)))
+
+(ert-deftest cconv-closure-convert-remap-var ()
+  ;; Verify that we correctly remap shadowed lambda-lifted variables.
+
+  ;; We intern all symbols for ease of comparison; this works because
+  ;; the `cconv-closure-convert' result should contain no pair of
+  ;; distinct symbols having the same name.
+
+  ;; Sanity check: captured variable, no lambda-lifting or shadowing:
+  (should (equal (cconv-tests--intern-all
+           (cconv-closure-convert
+            '#'(lambda (x)
+                 #'(lambda () x))))
+           '#'(lambda (x)
+                (internal-make-closure
+                 nil (x) nil
+                 (internal-get-closed-var 0)))))
+
+  ;; Basic case:
+  ;; - with `let':
+  (should (equal (cconv-tests--intern-all
+                  (cconv-closure-convert
+                   '#'(lambda (x)
+                        (let ((f #'(lambda () x)))
+                          (let ((x 'b))
+                            (list x (funcall f)))))))
+                 '#'(lambda (x)
+                      (let ((f #'(lambda (x) x)))
+                        (let ((x 'b)
+                              (closed-x x))
+                          (list x (funcall f closed-x)))))))
+  ;; - with `let*':
+  (should (equal (cconv-tests--intern-all
+                  (cconv-closure-convert
+                   '#'(lambda (x)
+                        (let ((f #'(lambda () x)))
+                          (let* ((x 'b))
+                            (list x (funcall f)))))))
+                 '#'(lambda (x)
+                      (let ((f #'(lambda (x) x)))
+                        (let* ((closed-x x)
+                               (x 'b))
+                          (list x (funcall f closed-x)))))))
+
+  ;; With the lambda-lifted shadowed variable also being captured:
+  ;; - with `let':
+  (should (equal (cconv-tests--intern-all
+                  (cconv-closure-convert
+                   '#'(lambda (x)
+                        #'(lambda ()
+                            (let ((f #'(lambda () x)))
+                              (let ((x 'a))
+                                (list x (funcall f))))))))
+                 '#'(lambda (x)
+                      (internal-make-closure
+                       nil (x) nil
+                       (let ((f #'(lambda (x) x)))
+                         (let ((x 'a)
+                               (closed-x (internal-get-closed-var 0)))
+                           (list x (funcall f closed-x))))))))
+  ;; - with `let*':
+  (should (equal (cconv-tests--intern-all
+                  (cconv-closure-convert
+                   '#'(lambda (x)
+                        #'(lambda ()
+                            (let ((f #'(lambda () x)))
+                              (let* ((x 'a))
+                                (list x (funcall f))))))))
+                 '#'(lambda (x)
+                      (internal-make-closure
+                       nil (x) nil
+                       (let ((f #'(lambda (x) x)))
+                         (let* ((closed-x (internal-get-closed-var 0))
+                                (x 'a))
+                           (list x (funcall f closed-x)))))))))
+
 (provide 'cconv-tests)
 ;;; cconv-tests.el ends here

--Apple-Mail=_D7447F0A-66F7-4083-8BF3-8B7D56A60FC3--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 17:23:03 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 20 12:23:03 2021
Received: from localhost ([127.0.0.1]:43631 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moU4t-0006fq-0G
	for submit <at> debbugs.gnu.org; Sat, 20 Nov 2021 12:23:03 -0500
Received: from mail-ed1-f47.google.com ([209.85.208.47]:39630)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pogonyshev@HIDDEN>) id 1moU4q-0006f6-Ae
 for 51982 <at> debbugs.gnu.org; Sat, 20 Nov 2021 12:23:01 -0500
Received: by mail-ed1-f47.google.com with SMTP id w1so56688238edc.6
 for <51982 <at> debbugs.gnu.org>; Sat, 20 Nov 2021 09:23:00 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=Tg75nvgiXvznmQpdN/HuZZYr+aNZj/Q+a2DjHxh5vXE=;
 b=kccV+T0Or+JSIOtLZ3GBa9YYuFy9/OzDX7kGImsP/b/Nh580F9g+LLd5Ofg07PnWn3
 dMAUnJI+eDCwqn7or7SNkXLpzGGeP2/Sy/QK3nQ/zMCRRm4OF/OVVIOzTbc/TVX2iAXr
 0ZF4vKZs+PZ+urzgHyTpmccNvu4DBONG5wFFScv5XFxNyLb7CTZa1cBqNiUpO35z6zYA
 2laoujCBZUpkxDG9GoktMwy/lzldfv7Atd6o+Dpq+xWljN4brU+HC+u3TgktXMcvJcHO
 Xz6g1aTrHJY3oS0JnSLMcQIoFf6otOxHekx5hIsrS5Rqdk3dYYTLsQhFBE4YErIixi38
 DFcQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=Tg75nvgiXvznmQpdN/HuZZYr+aNZj/Q+a2DjHxh5vXE=;
 b=fIEZhitkqNXZVA7Fc+cfpdBSBStyy+HmTCfJkw33VSfZP0ppLCXk6Tmxe+ILsPdxwq
 Ak0GQZ639/fxFkGowpyiNvDG+HDJ8dMevmgWLAqq4NE5/ec8nIinBtCOQzkMrRmTujjD
 qPShP6IA2ji9+OCQazUX2W//2NJSdu2pqvgo0Y3jdCi50+WfS7dJXPt2MSOHZOvQpkhu
 613BB8tF/ULqRKSrCArzA4uCCijOAqGO6IjTiJr276bUqZUvB8XbNLzmDy9zqlwRgeW8
 MyBAHZ1CHtRp55Ds5QE7H1PXhs7jBEZMUgcxYEtmNud+Rhqa+OIGevhmNbl22vlnb9sA
 REPw==
X-Gm-Message-State: AOAM533lqUXUFw2D63rN7oeJfE6GyoEXLbNHM5JFf8wmdA1YO61NNzyr
 6XL4buoGyK4Cth7A0RrkwYzUFwNITneOn9mS0w==
X-Google-Smtp-Source: ABdhPJyT3QfeZk79QJSRyoyErc1tlS8bfKckCfQcpTYopSxmiSQ5RURq9IMT0ZBLjmKnPuXcUV6GaP6WD0X9ONoNp0U=
X-Received: by 2002:a17:906:4fcc:: with SMTP id
 i12mr20986767ejw.309.1637428974346; 
 Sat, 20 Nov 2021 09:22:54 -0800 (PST)
MIME-Version: 1.0
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
 <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
In-Reply-To: <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
From: Paul Pogonyshev <pogonyshev@HIDDEN>
Date: Sat, 20 Nov 2021 18:22:43 +0100
Message-ID: <CAG7BparLwp_cP51hhvOME_DaoDDdc8yuyLiUz2bbRimoNUzXZQ@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
To: =?UTF-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Content-Type: multipart/alternative; boundary="0000000000005c653f05d13ba42c"
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Stefan Monnier <monnier@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--0000000000005c653f05d13ba42c
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

> you cannot count on an eventual fix to be back-ported to Emacs 28

Uh, it's not even released yet. Are the stabilization rules so strict that
even a *fix* cannot go in? Unless it is going to be a rewrite of half the
file...

Paul

On Sat, 20 Nov 2021 at 18:04, Mattias Engdeg=C3=A5rd <mattiase@HIDDEN> wro=
te:

> 20 nov. 2021 kl. 17.54 skrev Paul Pogonyshev <pogonyshev@HIDDEN>:
>
> > I consider this bug pretty important.
>
> You are not alone! However, it's been there for quite a long time so you
> cannot count on an eventual fix to be back-ported to Emacs 28, much less
> older releases. If you value compatibility with old versions, be prepared
> for work-arounds.
>
> For that matter I know exactly what's wrong and am currently weighing
> various solutions.
>
>

--0000000000005c653f05d13ba42c
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">&gt; you cannot count on an eventual fix to be back-ported=
 to Emacs 28<div><br></div><div>Uh, it&#39;s not even released yet. Are the=
 stabilization rules so strict that even a *fix* cannot go in? Unless it is=
 going to be a rewrite of half the file...</div><div><br></div><div>Paul</d=
iv></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_att=
r">On Sat, 20 Nov 2021 at 18:04, Mattias Engdeg=C3=A5rd &lt;<a href=3D"mail=
to:mattiase@HIDDEN">mattiase@HIDDEN</a>&gt; wrote:<br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex">20 nov. 2021 kl. 17.54 skrev Paul Pogo=
nyshev &lt;<a href=3D"mailto:pogonyshev@HIDDEN" target=3D"_blank">pogony=
shev@HIDDEN</a>&gt;:<br>
<br>
&gt; I consider this bug pretty important.<br>
<br>
You are not alone! However, it&#39;s been there for quite a long time so yo=
u cannot count on an eventual fix to be back-ported to Emacs 28, much less =
older releases. If you value compatibility with old versions, be prepared f=
or work-arounds.<br>
<br>
For that matter I know exactly what&#39;s wrong and am currently weighing v=
arious solutions.<br>
<br>
</blockquote></div>

--0000000000005c653f05d13ba42c--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 17:04:13 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 20 12:04:13 2021
Received: from localhost ([127.0.0.1]:43586 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moTmf-0003tm-9c
	for submit <at> debbugs.gnu.org; Sat, 20 Nov 2021 12:04:13 -0500
Received: from mail18c50.megamailservers.eu ([91.136.10.28]:38646)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1moTmc-0003tX-7h
 for 51982 <at> debbugs.gnu.org; Sat, 20 Nov 2021 12:04:11 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1637427847;
 bh=R/Z6mv/73qQtpFJevv13+Yh7wofxe68TlfJWfUfVfAg=;
 h=Subject:From:In-Reply-To:Date:Cc:References:To:From;
 b=L8H5nZcxieLmwmzDaRk0tHE0GsjhAPQLwj79q0IKd20BsX4zXgErSI/qjKHwHxzvB
 CIU5dJbkwN79SarFJ6WgkdO0zdgRx1vztriolbibwLvKsC8mQQL1pW8jbnvrL1QJg7
 P/BaE9fq7chsxSDkMAvWZRysrwPuZmuq7r23fXyU=
Feedback-ID: mattiase@HIDDEN
Received: from [192.168.0.4] (c188-150-171-71.bredband.tele2.se
 [188.150.171.71]) (authenticated bits=0)
 by mail18c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AKH44kL026797; 
 Sat, 20 Nov 2021 17:04:06 +0000
Content-Type: text/plain;
	charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
In-Reply-To: <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
Date: Sat, 20 Nov 2021 18:04:04 +0100
Content-Transfer-Encoding: quoted-printable
Message-Id: <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
 <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
To: Paul Pogonyshev <pogonyshev@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F16.61992A87.004A, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=GKNrrsBK c=1 sm=1 tr=0 ts=61992a87
 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17
 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=pGLkceISAAAA:8
 a=6gV9F8qI7Iccj_f2u08A:9 a=CjuIK1q_8ugA:10
X-Origin-Country: SE
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: 51982
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>,
 Stefan Monnier <monnier@HIDDEN>, 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

20 nov. 2021 kl. 17.54 skrev Paul Pogonyshev <pogonyshev@HIDDEN>:

> I consider this bug pretty important.

You are not alone! However, it's been there for quite a long time so you =
cannot count on an eventual fix to be back-ported to Emacs 28, much less =
older releases. If you value compatibility with old versions, be =
prepared for work-arounds.

For that matter I know exactly what's wrong and am currently weighing =
various solutions.





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 16:55:08 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 20 11:55:08 2021
Received: from localhost ([127.0.0.1]:43574 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moTds-0003cD-5P
	for submit <at> debbugs.gnu.org; Sat, 20 Nov 2021 11:55:08 -0500
Received: from mail-ed1-f41.google.com ([209.85.208.41]:34559)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pogonyshev@HIDDEN>) id 1moTdp-0003bS-Pm
 for 51982 <at> debbugs.gnu.org; Sat, 20 Nov 2021 11:55:07 -0500
Received: by mail-ed1-f41.google.com with SMTP id x15so56486425edv.1
 for <51982 <at> debbugs.gnu.org>; Sat, 20 Nov 2021 08:55:05 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=chT3W6AY6X7eSZ7Zq01pSeRW0vVZtQcQ90aMn8aBjv4=;
 b=SUsA48eYvdVsZk+bxrB2vjmfp9VTqr5RF1/CHFXzV2lhedIH5VrvQ4afIp6Z1HKJE9
 oPPHLvfgUY0poEu7O5BfPOF2rTEnPx/3jIwg5E1FAoUr9zaLxHQr+BWz3zVJw1V7w+nE
 jpR5pTPGWX+rDJnWU4nx4Qlab7c64sONCcua1SbVdiZ+q+r1cqmXiswzSG/CtntTeCDg
 V2uXG07+fHsCA+9JSrxZwTraHjP6A6Tj3MVw3RoKWJUHX9lTeFuO1H907bQPnFHCyfY6
 sDw492yYDFywnAQ/bXwv4JbkHzVAQe9xbFwep7x7JYLrAWZCpvbp3yNYRTbBHBtM10Iu
 B2WQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=chT3W6AY6X7eSZ7Zq01pSeRW0vVZtQcQ90aMn8aBjv4=;
 b=N2yYP1YHRXVjozycCPt4i/6E201N0xMTkKCFSw2xesIyFGoCpuGWDQKcaEdBxFj5Tz
 IkQyNl9QTK+2cEa1OffoZRk3p7lorc+bOmPfJ8P2IzPkFpdbQrNH73TzcwhWutgJ/mKS
 6TxZO7A5LQlrBxJ/ZxAELBke0potqz70n7J7l0XzkHQwsCEeEmeB9XrPGvA2eXepxUuf
 4LOF4Wg2zPVHWIzAB7UGxXVkEmLWjJorJECV/CyE89PkqYdtLJMWrQ+C0tnNBXiOjQtp
 7W3iPKeJR0j3OXCCW907KxkbdzJcafZ+W71cw7x4QaA2a8LDxgLJzsHdvsRpV/Ip2eyy
 /7dw==
X-Gm-Message-State: AOAM531R7F84rFXVYG0jVpYIkigo5QmDsCVYv6hAN445bluMRZWuOGiO
 Vsd10bbZ7Y4s5s6//NcB79EVh4e9A8djtHCQTg==
X-Google-Smtp-Source: ABdhPJywb9GV315OGw7OsTwyhnSvgcSUnwMdYFMFo7iafQ6SrOCFpolvaDI+YHdKxreJMgKq+kzwexDf6LTXzfvxN9A=
X-Received: by 2002:a17:907:2da1:: with SMTP id
 gt33mr20703662ejc.378.1637427299594; 
 Sat, 20 Nov 2021 08:54:59 -0800 (PST)
MIME-Version: 1.0
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
In-Reply-To: <87y25jo2q1.fsf@HIDDEN>
From: Paul Pogonyshev <pogonyshev@HIDDEN>
Date: Sat, 20 Nov 2021 17:54:49 +0100
Message-ID: <CAG7Bpaq-hcZaMG2sEC8UjYo+7WFW-gm99W1wHeeVfuduUmcu3A@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
To: Michael Heerdegen <michael_heerdegen@HIDDEN>
Content-Type: multipart/alternative; boundary="00000000000089b44205d13b4052"
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 51982
Cc: mattiase@HIDDEN, Stefan Monnier <monnier@HIDDEN>,
 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--00000000000089b44205d13b4052
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Just to note: I consider this bug pretty important. The example function
looks artificial, but I got the real failure by combining macros from
different packages (`dash.el' for all the `it' bindings, plus `pcase' and
`iter2' for lambdas, but I'm pretty sure you could get a failure with
nested complicated `pcase' alone, if you want to go "only built-in" route).
So, while it is apparently unlikely, you still can stumble into an
incomprehensible breakdown in any sofisticated function by nesting enough
macros that work otherwise and actually produce code that should work also
in this case. But doesn't, when byte-compiled.

Paul

On Sat, 20 Nov 2021 at 05:44, Michael Heerdegen <michael_heerdegen@HIDDEN>
wrote:

> Hello Paul,
>
> thanks for the report, I can reproduce the issue, there is something
> going wrong when compiling.  I guess this is something for Mattias or
> Stefan maybe? (CC'd)
>
> #+begin_src emacs-lisp
> ; -*- lexical-binding: t -*-
>
> (defun wtf (x)
>   (let ((it 0))
>     #'(lambda ()
>         (let ((fn #'(lambda () it)))
>           (if x
>               (let ((it x))
>                 it)
>             (funcall fn))))))
> #+end_src
>
> Byte compile:
>
> >     wtf.el:9:17:Warning: reference to free variable =E2=80=98it=E2=80=
=99
>
> (funcall (wtf 1))
>
> >     Symbol=E2=80=99s value as variable is void: it
>
> while expected result is 1.  Uncompiled code works as expected.
>
> TIA,
>
> Michael.
>

--00000000000089b44205d13b4052
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Just to note: I consider this bug pretty important. The ex=
ample function looks artificial, but I got the real failure by combining ma=
cros from different packages (`dash.el&#39; for all the `it&#39; bindings, =
plus `pcase&#39; and `iter2&#39; for lambdas, but I&#39;m pretty sure you c=
ould get a failure with nested complicated `pcase&#39; alone, if you want t=
o go &quot;only built-in&quot; route). So, while it is apparently unlikely,=
 you still can stumble into an incomprehensible breakdown in any sofisticat=
ed function by nesting enough macros that work otherwise and actually produ=
ce code that should work also in this case. But doesn&#39;t, when byte-comp=
iled.<div><br></div><div>Paul</div></div><br><div class=3D"gmail_quote"><di=
v dir=3D"ltr" class=3D"gmail_attr">On Sat, 20 Nov 2021 at 05:44, Michael He=
erdegen &lt;<a href=3D"mailto:michael_heerdegen@HIDDEN">michael_heerdegen@w=
eb.de</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex">Hello Paul,<br>
<br>
thanks for the report, I can reproduce the issue, there is something<br>
going wrong when compiling.=C2=A0 I guess this is something for Mattias or<=
br>
Stefan maybe? (CC&#39;d)<br>
<br>
#+begin_src emacs-lisp<br>
; -*- lexical-binding: t -*-<br>
<br>
(defun wtf (x)<br>
=C2=A0 (let ((it 0))<br>
=C2=A0 =C2=A0 #&#39;(lambda ()<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((fn #&#39;(lambda () it)))<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if x<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((it x))<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 it)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (funcall fn))))))<br>
#+end_src<br>
<br>
Byte compile:<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0wtf.el:9:17:Warning: reference to free variable =E2=
=80=98it=E2=80=99<br>
<br>
(funcall (wtf 1))<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Symbol=E2=80=99s value as variable is void: it<br>
<br>
while expected result is 1.=C2=A0 Uncompiled code works as expected.<br>
<br>
TIA,<br>
<br>
Michael.<br>
</blockquote></div>

--00000000000089b44205d13b4052--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 10:51:34 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 20 05:51:34 2021
Received: from localhost ([127.0.0.1]:41851 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moNy2-00074y-Fd
	for submit <at> debbugs.gnu.org; Sat, 20 Nov 2021 05:51:34 -0500
Received: from mout.web.de ([212.227.17.11]:58397)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <michael_heerdegen@HIDDEN>) id 1moNy0-00074j-SO
 for 51982 <at> debbugs.gnu.org; Sat, 20 Nov 2021 05:51:33 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de;
 s=dbaedf251592; t=1637405480;
 bh=EflmmCJroIYjhtQTAJQYM4Ss99pTl2LtBUli8hJNFqc=;
 h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To;
 b=GLtHTVJh297meTq6H88tHUmYiIIVL3uKEfFIztIEMR6iTQXjPjMOKD0egpHe+PMwu
 i8C6+V8CtUvDoW3SBTemMaXihIAzAN37IOboA8hnjdL31hTIwjP0Z1RjIYHta2ad/h
 OPtWm9VZvhgCQLBFeaq1Il8q21jkxyeSQ+aYdCQU=
X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9
Received: from drachen.dragon ([92.208.225.87]) by smtp.web.de (mrweb105
 [213.165.67.124]) with ESMTPSA (Nemesis) id 1M2xrq-1mnIZA1Eei-003p6K; Sat, 20
 Nov 2021 11:51:20 +0100
From: Michael Heerdegen <michael_heerdegen@HIDDEN>
To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in
 byte-compiled nested lambdas
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN> <8EBD8765-6043-473D-9A42-3B2BF46EB6B5@HIDDEN>
Date: Sat, 20 Nov 2021 11:51:18 +0100
In-Reply-To: <8EBD8765-6043-473D-9A42-3B2BF46EB6B5@HIDDEN> ("Mattias
 =?utf-8?Q?Engdeg=C3=A5rd=22's?= message of "Sat, 20 Nov 2021 09:45:30
 +0100")
Message-ID: <87czmv85i1.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Provags-ID: V03:K1:JycIC29bQsBlSlHeECjAkKjpV3JmfuuHMyos85zFvwkSy18wy4T
 jGpYprwCPde/wX2uqHUsv+CfvCcTG2AmMavliBe56gQm5cKiGFFlJ0kWLsXswqZzz73Zqy/
 emT+pymbNcW7jD8W9aylrnSvtTeE2nSYcFzu9nmO7nlqo6QtiCy84KNR0rMu3C85yAYBi9b
 gUeYpBj3zbAYVcatUVkxw==
X-Spam-Flag: NO
X-UI-Out-Filterresults: notjunk:1;V03:K0:hkqrl0V70ng=:rPw87+Wna0N3XgpAL94Fn0
 92MOBlQA9Z+sSOqz1Wab4UCCPzId2TqR5fcGEKTACT/oa2bqUalYV9uEXIVvHxau+PDUp1MtU
 Y2Nt/youEgbZLQIcUKfqVDXCd85WbLEkkgH6vTQ81upsmR1+GJ3ltw7j4p8fT7LRwIiSit+aI
 2Y0yiNsrkVo4oj6tJNhrnbPFztIMszUc7oc5VumnodqRBblwMTwSoHhRoH2EwiE0gepuYoedS
 46AZeiFVxh+oAvKBP8iTL5rjhAwafkOM6dQwneK/uiBEbKrv6oVVy7qY94esBETnCejJC4mr5
 vtZkjG13Pjm7bX8dO+AI1A0vPQuoJq2SBuxx78ChA7zKdz9SOXNS9lhcOCvOwi46FChRVrMiF
 /d6G25h+k7aiI+dbfWNEvJ8YXNMjXTacheUGt/IR5HuNKfUMO5YQ8zN65fV79jo2xRSIt+P/M
 x6j3cFAPBP8e3+cty8HEd/YzCUZqdLgHf2bssrlaXA93yfhAXjny/54woEujb36EXao3sb5Lj
 qzmTgjHi8My64fr8RjcgJ3iihrfGq5Iwa+8IjKIiIpHPUcB3m/dMy3QDfagfZsNqNlsQZ+fgc
 UNvOqRPjGKQWlHhDeppythUP+V3OpPlToBQ9Ea4G6o2qSDXUqDlcdDt+uccdxSomlKHltxNRh
 mCMuvFMXlO2MnVh7fsJWdswC0WwsL8m2+dvhxEY6MEuKhqztfBxCcJGy42lFOf/pnx098VIZb
 ab/hY0Ctp1r/HM4OJi5S+gvFz6D6VgGz+00gUo8H5+971S3j0zYM+/AINDIr563nep72B5lQo
 mszW/I/p6O+MW8v5wxnLIaTIDX0senOzi5TFQC+VPczJ++fR+AiOluM91IKl70GXgRqjmxWpL
 YjTpAJeO44iHhm+WteuDL9tkPepAi5AZZ2Qst2E9fd2Mj8SSQNNRzUFgR8JX/QEzEVfolDrqH
 +ZkBgSlnarokI3N/tetpxYtQpZGw8wiNyDknnlB9SUI3I7aEsv5vTG7T+5Yrx5Jl2UhkSGcPF
 +7XAS35m22qf2e97Ps72Qx10JiX/FEeoTlQmSpKCHm/ySXYVNxkNPPO97+tFiVT2avTTELjaE
 1R4Ox/dJyP93A8=
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 51982
Cc: Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org,
 Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Mattias Engdeg=C3=A5rd <mattiase@HIDDEN> writes:

> Yes, looks like a bug in cconv. Fun! I'll have a look.

Ok - that's what I guessed.  Thanks for checking.

Michael.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 08:45:40 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 20 03:45:40 2021
Received: from localhost ([127.0.0.1]:41629 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moM0C-0007GX-5F
	for submit <at> debbugs.gnu.org; Sat, 20 Nov 2021 03:45:40 -0500
Received: from mail200c50.megamailservers.eu ([91.136.10.210]:50412
 helo=mail193c50.megamailservers.eu)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@HIDDEN>) id 1moM08-0007GK-VF
 for 51982 <at> debbugs.gnu.org; Sat, 20 Nov 2021 03:45:38 -0500
X-Authenticated-User: mattiase@HIDDEN
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1637397934;
 bh=U3pnNyCCN1SBQR1GRcgOI8y1bgZxtnMAxDcIVQzsu+o=;
 h=Subject:From:In-Reply-To:Date:Cc:References:To:From;
 b=a04D17pUN2DvOxFPlnQkeiQOi8VbNPF7uo224DKwvDUhr0LlHK+yBsj1TS1eGbX0S
 ugD6qHGL+ubhktRei7O3EMfzMYQnwBjXYZxfMMKUDlcIej9P3D0UQlssCv85S9MRFU
 WfMvaOMMj4EFz+9SznYV7x+0JgzdCx2oQUivMU9M=
Feedback-ID: mattiase@HIDDEN
Received: from [192.168.0.4] (c188-150-171-71.bredband.tele2.se
 [188.150.171.71]) (authenticated bits=0)
 by mail193c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AK8jVFO018045; 
 Sat, 20 Nov 2021 08:45:33 +0000
Content-Type: text/plain;
	charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\))
Subject: Re: bug#51982: Erroneous handling of local variables in byte-compiled
 nested lambdas
From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
In-Reply-To: <87y25jo2q1.fsf@HIDDEN>
Date: Sat, 20 Nov 2021 09:45:30 +0100
Content-Transfer-Encoding: 7bit
Message-Id: <8EBD8765-6043-473D-9A42-3B2BF46EB6B5@HIDDEN>
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 <87y25jo2q1.fsf@HIDDEN>
To: Michael Heerdegen <michael_heerdegen@HIDDEN>
X-Mailer: Apple Mail (2.3445.104.21)
X-CTCH-RefID: str=0001.0A742F18.6198B5AE.0027, ss=1, re=0.000, recu=0.000,
 reip=0.000, cl=1, cld=1, fgs=0
X-CTCH-VOD: Unknown
X-CTCH-Spam: Unknown
X-CTCH-Score: 0.000
X-CTCH-Rules: 
X-CTCH-Flags: 0
X-CTCH-ScoreCust: 0.000
X-CSC: 0
X-CHA: v=2.4 cv=LIkF/La9 c=1 sm=1 tr=0 ts=6198b5ae
 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17
 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=1UtpXadrpKWgyzGnBRoA:9
 a=CjuIK1q_8ugA:10 a=NN3w1SoFm1sA:10 a=usTng3WFuU040fz4oTA4:22
X-Origin-Country: SE
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: 51982
Cc: Paul Pogonyshev <pogonyshev@HIDDEN>, 51982 <at> debbugs.gnu.org,
 Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

20 nov. 2021 kl. 05.44 skrev Michael Heerdegen <michael_heerdegen@HIDDEN>:

> there is something going wrong when compiling.

Yes, looks like a bug in cconv. Fun! I'll have a look.





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at 51982 <at> debbugs.gnu.org:


Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 04:45:09 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Nov 19 23:45:09 2021
Received: from localhost ([127.0.0.1]:41303 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moIFQ-0008Ih-Vx
	for submit <at> debbugs.gnu.org; Fri, 19 Nov 2021 23:45:09 -0500
Received: from mout.web.de ([217.72.192.78]:46611)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <michael_heerdegen@HIDDEN>) id 1moIFO-0008Hp-9a
 for 51982 <at> debbugs.gnu.org; Fri, 19 Nov 2021 23:45:07 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de;
 s=dbaedf251592; t=1637383480;
 bh=WSjuCKGs8S6v/GOpQOQLx1DL0lMqXAZL6fGS0f185+g=;
 h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To;
 b=Dc1LuDRlyWmvhQIncGS7q1zQklYvHQpRstse4yP3IFgW7uIab2MxmactY8iHFaWPT
 TtCIS6YLIbaVzq1//SCL1VvFZHHuNpzwenMTTC6w7Dep/VTqkObOaxoohpmwlMlEIl
 Fe0j2JubOY/9jXkjb6iARxustTtPvci530ItMGdc=
X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9
Received: from drachen.dragon ([92.208.225.87]) by smtp.web.de (mrweb105
 [213.165.67.124]) with ESMTPSA (Nemesis) id 1N1LwP-1me98V0msN-012M1Y; Sat, 20
 Nov 2021 05:44:40 +0100
From: Michael Heerdegen <michael_heerdegen@HIDDEN>
To: Paul Pogonyshev <pogonyshev@HIDDEN>
Subject: Re: bug#51982: Erroneous handling of local variables in
 byte-compiled nested lambdas
References: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
Date: Sat, 20 Nov 2021 05:44:38 +0100
In-Reply-To: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
 (Paul Pogonyshev's message of "Fri, 19 Nov 2021 21:31:13 +0100")
Message-ID: <87y25jo2q1.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Provags-ID: V03:K1:UwrhlAbDSqcubECPvw3reGpIk8S5g/tWKxmtbpOCs1asLZJY+RG
 YGUUgBpacOUSJdWv0bH0OvD1m7I06Oo4SwgPUqLHPLhx8Mw0P9f0NGzbi0Ds1W7XMprHjOv
 DTXgGC/U6XSUH8v2kvp8RDBHqA8pIuWGxuQO5MgtSCRL142ZSIQVPPMneRtayxcYgy+HwUE
 EmcB5K+4zK45zFdyPRFUQ==
X-Spam-Flag: NO
X-UI-Out-Filterresults: notjunk:1;V03:K0:L7kat2YFHQ0=:cm3c3z9ePPIkYQHPlHGdjG
 r4g0vwaMRuo0nJWktG0laoMj2UTHJcfA1cuT+t/SX4a1u+l57Yp/dd4UASVISxCH8wpz1hScE
 TE1JN7PA0XrGDt91x6WJCUx6qCTZ+6WZDRCNiWqnaG3lFsQxMUlXR5feN9U2YM/0d0QM63vUc
 f5vE92zDLWPFIRKUgk4dwBBPy5WZC8+tFUaDdqTtrW+4wu9spwQAPtRn4h9ao4r5Q7AaEEwxO
 Zt3GQsVKjzcagIwxIFlg95ORwEjyX4PBoNL/iNOML90FJqWMa34GAluSHO/nZfh1bLGR9EjwA
 M2xPfFNXZZeZ+a6ZW5468u2L8yN7HsLKEoZSzJ7Hfsuz0tZJI18XFDV2yMTA5IEudDqrKZ6an
 bgCeoVDGJok9YyNY29Js+DfcAaC+EfjZR2RMqL+E04jHL75/Od5eRENY4Qn2AMsd2iI8Qb4pg
 Poekpmf5Ozex5TUHZ5QEXSHItlaXhOM2oMaXgMQdspS+p/qpI6Zjb+2GqTfRv6J5AAaN8CWRH
 uXSBwMbtgXdCfcCwP/v3OKw5J142vXnP3QdflZQ4tVDnAoyI8NcAVAHBpcoiDG4alUKXlDkXx
 OUT6dIKeMAmYzzEWrRs61FGlRGsCo5BthMZLJVfuMoIGDaEoxeymKt0Z/8rGapUSdaqAZUObk
 tFx0/HtJqbnPwmP6x73N3Jys/cQPgkNtKth3lpVgQf65eN4CK4R8Finbzx60z+sBzRrIzaULN
 romhfhSuEzqA8hLb49F94D9ru3VicejhjH3j+MO37258JCStE1Fz/eOggSgoiT0SGGxW0Mc0q
 u2y4uXIqKVNcEsH/s9Ce13B+//xle5Nl2p/0x7PgW4hZ0Ww50nils217hDYmUMMs33c9Vp4lK
 tiUWxs1onlSouYYivK21eAjs/pc8cYKEYyKCzmV+uQo1Y5A1c7ix7CBGzHysJ92jnnEVDX+m/
 NrqiexGBqeyJATW1Ii2rFygW7O5VRPpWI0tKFNyAFFVhbYS/qTKLAGm30cODgGNoASSKqJewt
 ptHDBTrj0hd/XOjvx1waapedx6toPgINEEQiTtec4FJeeMMeRBaUeoaRyy7qT1C+eAvL3g2mW
 dCqfw5o+CqtuUc=
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 51982
Cc: mattiase@HIDDEN, Stefan Monnier <monnier@HIDDEN>,
 51982 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

Hello Paul,

thanks for the report, I can reproduce the issue, there is something
going wrong when compiling.  I guess this is something for Mattias or
Stefan maybe? (CC'd)

#+begin_src emacs-lisp
; -*- lexical-binding: t -*-

(defun wtf (x)
  (let ((it 0))
    #'(lambda ()
        (let ((fn #'(lambda () it)))
          (if x
              (let ((it x))
                it)
            (funcall fn))))))
#+end_src

Byte compile:

>     wtf.el:9:17:Warning: reference to free variable =E2=80=98it=E2=80=99

(funcall (wtf 1))

>     Symbol=E2=80=99s value as variable is void: it

while expected result is 1.  Uncompiled code works as expected.

TIA,

Michael.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 19 Nov 2021 20:31:36 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Nov 19 15:31:36 2021
Received: from localhost ([127.0.0.1]:40619 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1moAXn-0006Sx-Rv
	for submit <at> debbugs.gnu.org; Fri, 19 Nov 2021 15:31:36 -0500
Received: from lists.gnu.org ([209.51.188.17]:45562)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pogonyshev@HIDDEN>) id 1moAXl-0006Sp-Nb
 for submit <at> debbugs.gnu.org; Fri, 19 Nov 2021 15:31:33 -0500
Received: from eggs.gnu.org ([209.51.188.92]:51082)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <pogonyshev@HIDDEN>)
 id 1moAXl-0004aI-Hw
 for bug-gnu-emacs@HIDDEN; Fri, 19 Nov 2021 15:31:33 -0500
Received: from [2a00:1450:4864:20::529] (port=33334
 helo=mail-ed1-x529.google.com)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <pogonyshev@HIDDEN>)
 id 1moAXe-0007vG-RF
 for bug-gnu-emacs@HIDDEN; Fri, 19 Nov 2021 15:31:33 -0500
Received: by mail-ed1-x529.google.com with SMTP id t5so47800546edd.0
 for <bug-gnu-emacs@HIDDEN>; Fri, 19 Nov 2021 12:31:25 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:from:date:message-id:subject:to;
 bh=g5Zs4MTGtu2gvyWPcqkEHir87kJdXKULalDFNxCLweA=;
 b=YJfNSuyqa9ks+v/YK5PHgdf8P+OxqSZS6B+vsOATyxbhZwP/gdUuIF1e0VATyhHwp/
 QKNS4E6U+txcGOerx+QtJQ22S8LDjbzVJMwUCMwf+Ewwum8WIKsMmGcqjfOzoCI1B0Ln
 2lPblh4cQjLGrFOK3M6VkZCRpGcYPEz9BDW5iPgHDFH/1eY0oBBgp8TvT11t6icIflll
 b5r/V3iItkhG9XAdbTlWORL/cwCMktC7iXgD7XkaPrXHFwPxOXZUiuxhi5IQI+X3/sNP
 +Qg8qStqhKcICODDRGVIlqsbPQThrQfcKu4iyiQ9pnh1CneXN9UQ3Z+vBktm5PMeNBLb
 YMSQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:from:date:message-id:subject:to;
 bh=g5Zs4MTGtu2gvyWPcqkEHir87kJdXKULalDFNxCLweA=;
 b=7LFgZPuaA1rIlPCMrUWeS66JXH4iKrjhNo+oAYW2EIfczwcSY13C5CRqDl9JL8pgyL
 LtSmYCPy3yv1lYEvg7Z/Dj+HXXcvQ9BEoim6IR+xnxFRmzixFwOudE57CYSUMcGoJ8Mk
 eaEEHjHHZgwvTs1YYBt0ACXCsMIUEqvoGQJQFoIURjfGtlLCZY1rBCfWeoB4pTY4UKOR
 JoTdcEb/TSbpk2BBl6j/0pu5zvUSOWUQSMhtKjyRRIvd10RRVAtghUOGSkIWgjZC8lW+
 2Tv5BTxCSn04mxJMIawYHBdcU7LYtycAcc23zzldBQePVUoAYFfdSEIMh4sQJ3GOyqtS
 Qs4w==
X-Gm-Message-State: AOAM533LfQ1qR8uMBPVqC0gbdd3sPL/ov+a4umXvr4HvmuItk4hXx1D2
 YIwIpk7pRmjMdawyx0caPlYkx4FQ9Jeu6uZTU5QvzB2jAQ==
X-Google-Smtp-Source: ABdhPJxZ6dOV+PlbifOWhfYdZ5pm9wgS2Kqx5p+iWCL0VaywbJ23X/e7T1or24D69vs8vMCCTesfgfpCjyGCQg0Np38=
X-Received: by 2002:a17:907:3f24:: with SMTP id
 hq36mr11470790ejc.390.1637353884336; 
 Fri, 19 Nov 2021 12:31:24 -0800 (PST)
MIME-Version: 1.0
From: Paul Pogonyshev <pogonyshev@HIDDEN>
Date: Fri, 19 Nov 2021 21:31:13 +0100
Message-ID: <CAG7BpaoBrzWZK01+FAwhbO04HXgWXxGqe31GmphQOAA_Cgv3=g@HIDDEN>
Subject: Erroneous handling of local variables in byte-compiled nested lambdas
To: bug-gnu-emacs@HIDDEN
Content-Type: multipart/mixed; boundary="000000000000a5e8da05d12a282e"
X-Host-Lookup-Failed: Reverse DNS lookup failed for 2a00:1450:4864:20::529
 (failed)
Received-SPF: pass client-ip=2a00:1450:4864:20::529;
 envelope-from=pogonyshev@HIDDEN; helo=mail-ed1-x529.google.com
X-Spam_score_int: -12
X-Spam_score: -1.3
X-Spam_bar: -
X-Spam_report: (-1.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
 HTML_MESSAGE=0.001, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001,
 RDNS_NONE=0.793, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001 autolearn=no autolearn_force=no
X-Spam_action: no action
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -2.3 (--)

--000000000000a5e8da05d12a282e
Content-Type: multipart/alternative; boundary="000000000000a5e8d605d12a282c"

--000000000000a5e8d605d12a282c
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Steps to reproduce:

1) save attached file as `wtf.el';
2) execute from command line:

    $ emacs --batch --eval "(byte-compile-file \"wtf.el\")"
    $ emacs --batch -L . --eval "(require 'wtf)" --eval "(print (funcall
(wtf 1)))"

Results, of the first command (byte-compilation):

    In wtf:
    wtf.el:9:17:Warning: reference to free variable =E2=80=98it=E2=80=99

of the second:

    Symbol=E2=80=99s value as variable is void: it

Expected results: byte compilation succeeds without warnings, second
command prints "1".

Note that if you change line "(let ((fn #'(lambda () it)))" to e.g. "(let
((fn #'(lambda () nil)))", everything works as expected.  However, 'fn' _is
not even used_ when function `wtf' is called with non-nil argument, which
further conforms that the observed behavior is a bug.  Another indication:
when the function is not byte-compiled (e.g. delete file `wtf.elc' after
the first command), it produces expected results.

Function, of course, doesn't make any sense.  It is a result of removing
contents of real failure until it is as small as possible.

Paul

--000000000000a5e8d605d12a282c
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Steps to reproduce:<br><br>1) save attached file as `wtf.e=
l&#39;;<br>2) execute from command line:<br><br>=C2=A0 =C2=A0 $ emacs --bat=
ch --eval &quot;(byte-compile-file \&quot;wtf.el\&quot;)&quot;<br>=C2=A0 =
=C2=A0 $ emacs --batch -L . --eval &quot;(require &#39;wtf)&quot; --eval &q=
uot;(print (funcall (wtf 1)))&quot;<br><br>Results, of the first command (b=
yte-compilation):<br><br>=C2=A0 =C2=A0 In wtf:<br>=C2=A0 =C2=A0 wtf.el:9:17=
:Warning: reference to free variable =E2=80=98it=E2=80=99<br><br>of the sec=
ond:<br><br>=C2=A0 =C2=A0 Symbol=E2=80=99s value as variable is void: it<br=
><br>Expected results: byte compilation succeeds without warnings, second c=
ommand prints &quot;1&quot;.<br><br>Note that if you change line &quot;(let=
 ((fn #&#39;(lambda () it)))&quot; to e.g. &quot;(let ((fn #&#39;(lambda ()=
 nil)))&quot;, everything works as expected.=C2=A0 However, &#39;fn&#39; _i=
s not even used_ when function `wtf&#39; is called with non-nil argument, w=
hich further conforms that the observed behavior is a bug.=C2=A0 Another in=
dication: when the function is not byte-compiled (e.g. delete file `wtf.elc=
&#39; after the first command), it produces expected results.<br><br>Functi=
on, of course, doesn&#39;t make any sense.=C2=A0 It is a result of removing=
 contents of real failure until it is as small as possible.<br><br>Paul<br>=
</div>

--000000000000a5e8d605d12a282c--

--000000000000a5e8da05d12a282e
Content-Type: text/x-emacs-lisp; charset="US-ASCII"; name="wtf.el"
Content-Disposition: attachment; filename="wtf.el"
Content-Transfer-Encoding: base64
Content-ID: <f_kw6u7s8a0>
X-Attachment-Id: f_kw6u7s8a0

OyAtKi0gbGV4aWNhbC1iaW5kaW5nOiB0IC0qLQoKKGRlZnVuIHd0ZiAoeCkKICAobGV0ICgoaXQg
MCkpCiAgICAjJyhsYW1iZGEgKCkKICAgICAgICAobGV0ICgoZm4gIycobGFtYmRhICgpIGl0KSkp
CiAgICAgICAgICAoaWYgeAogICAgICAgICAgICAgIChsZXQgKChpdCB4KSkKICAgICAgICAgICAg
ICAgIGl0KQogICAgICAgICAgICAoZnVuY2FsbCBmbikpKSkpKQoKKHByb3ZpZGUgJ3d0ZikK
--000000000000a5e8da05d12a282e--




Acknowledgement sent to Paul Pogonyshev <pogonyshev@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#51982; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Thu, 2 Dec 2021 09:15:01 UTC

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