From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Paul Pogonyshev Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 19 Nov 2021 20:32:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: 51982@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.163735389624863 (code B ref -1); Fri, 19 Nov 2021 20:32:02 +0000 Received: (at submit) by debbugs.gnu.org; 19 Nov 2021 20:31:36 +0000 Received: from localhost ([127.0.0.1]:40619 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moAXn-0006Sx-Rv for submit@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 ) id 1moAXl-0006Sp-Nb for submit@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 ) id 1moAXl-0004aI-Hw for bug-gnu-emacs@gnu.org; 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 ) id 1moAXe-0007vG-RF for bug-gnu-emacs@gnu.org; Fri, 19 Nov 2021 15:31:33 -0500 Received: by mail-ed1-x529.google.com with SMTP id t5so47800546edd.0 for ; 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 Date: Fri, 19 Nov 2021 21:31:13 +0100 Message-ID: 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@gmail.com; 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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
Steps to reproduce:

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

=C2=A0 =C2=A0 $ emacs --bat= ch --eval "(byte-compile-file \"wtf.el\")"
=C2=A0 = =C2=A0 $ emacs --batch -L . --eval "(require 'wtf)" --eval &q= uot;(print (funcall (wtf 1)))"

Results, of the first command (b= yte-compilation):

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

of the sec= ond:

=C2=A0 =C2=A0 Symbol=E2=80=99s value as variable is void: it
Expected results: byte compilation succeeds without warnings, second c= ommand prints "1".

Note that if you change line "(let= ((fn #'(lambda () it)))" to e.g. "(let ((fn #'(lambda ()= nil)))", everything works as expected.=C2=A0 However, 'fn' _i= s not even used_ when function `wtf' 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= ' after the first command), it produces expected results.

Functi= on, of course, doesn't make any sense.=C2=A0 It is a result of removing= contents of real failure until it is as small as possible.

Paul
=
--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: X-Attachment-Id: f_kw6u7s8a0 OyAtKi0gbGV4aWNhbC1iaW5kaW5nOiB0IC0qLQoKKGRlZnVuIHd0ZiAoeCkKICAobGV0ICgoaXQg MCkpCiAgICAjJyhsYW1iZGEgKCkKICAgICAgICAobGV0ICgoZm4gIycobGFtYmRhICgpIGl0KSkp CiAgICAgICAgICAoaWYgeAogICAgICAgICAgICAgIChsZXQgKChpdCB4KSkKICAgICAgICAgICAg ICAgIGl0KQogICAgICAgICAgICAoZnVuY2FsbCBmbikpKSkpKQoKKHByb3ZpZGUgJ3d0ZikK --000000000000a5e8da05d12a282e-- From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Michael Heerdegen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 04:46:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Paul Pogonyshev Cc: mattiase@acm.org, Stefan Monnier , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163738350931915 (code B ref 51982); Sat, 20 Nov 2021 04:46:01 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 04:45:09 +0000 Received: from localhost ([127.0.0.1]:41303 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moIFQ-0008Ih-Vx for submit@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 ) id 1moIFO-0008Hp-9a for 51982@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 References: Date: Sat, 20 Nov 2021 05:44:38 +0100 In-Reply-To: (Paul Pogonyshev's message of "Fri, 19 Nov 2021 21:31:13 +0100") Message-ID: <87y25jo2q1.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 08:46:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Michael Heerdegen Cc: Paul Pogonyshev , 51982@debbugs.gnu.org, Stefan Monnier Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163739794027937 (code B ref 51982); Sat, 20 Nov 2021 08:46:02 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 08:45:40 +0000 Received: from localhost ([127.0.0.1]:41629 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moM0C-0007GX-5F for submit@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 ) id 1moM08-0007GK-VF for 51982@debbugs.gnu.org; Sat, 20 Nov 2021 03:45:38 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <87y25jo2q1.fsf@web.de> Date: Sat, 20 Nov 2021 09:45:30 +0100 Content-Transfer-Encoding: 7bit Message-Id: <8EBD8765-6043-473D-9A42-3B2BF46EB6B5@acm.org> References: <87y25jo2q1.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 20 nov. 2021 kl. 05.44 skrev Michael Heerdegen : > there is something going wrong when compiling. Yes, looks like a bug in cconv. Fun! I'll have a look. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Michael Heerdegen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 10:52:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Paul Pogonyshev , 51982@debbugs.gnu.org, Stefan Monnier Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163740549427220 (code B ref 51982); Sat, 20 Nov 2021 10:52:02 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 10:51:34 +0000 Received: from localhost ([127.0.0.1]:41851 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moNy2-00074y-Fd for submit@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 ) id 1moNy0-00074j-SO for 51982@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 References: <87y25jo2q1.fsf@web.de> <8EBD8765-6043-473D-9A42-3B2BF46EB6B5@acm.org> Date: Sat, 20 Nov 2021 11:51:18 +0100 In-Reply-To: <8EBD8765-6043-473D-9A42-3B2BF46EB6B5@acm.org> ("Mattias =?UTF-8?Q?Engdeg=C3=A5rd?="'s message of "Sat, 20 Nov 2021 09:45:30 +0100") Message-ID: <87czmv85i1.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Mattias Engdeg=C3=A5rd writes: > Yes, looks like a bug in cconv. Fun! I'll have a look. Ok - that's what I guessed. Thanks for checking. Michael. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Paul Pogonyshev Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 16:56:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Michael Heerdegen Cc: mattiase@acm.org, Stefan Monnier , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163742730813905 (code B ref 51982); Sat, 20 Nov 2021 16:56:01 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 16:55:08 +0000 Received: from localhost ([127.0.0.1]:43574 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moTds-0003cD-5P for submit@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 ) id 1moTdp-0003bS-Pm for 51982@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@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: <87y25jo2q1.fsf@web.de> In-Reply-To: <87y25jo2q1.fsf@web.de> From: Paul Pogonyshev Date: Sat, 20 Nov 2021 17:54:49 +0100 Message-ID: Content-Type: multipart/alternative; boundary="00000000000089b44205d13b4052" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 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
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' for all the `it' bindings, = plus `pcase' and `iter2' for lambdas, but I'm pretty sure you c= ould get a failure with nested complicated `pcase' alone, if you want t= o go "only built-in" 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't, when byte-comp= iled.

Paul

On Sat, 20 Nov 2021 at 05:44, Michael He= erdegen <michael_heerdegen@w= eb.de> wrote:
Hello Paul,

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

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

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

Byte compile:

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

(funcall (wtf 1))

>=C2=A0 =C2=A0 =C2=A0Symbol=E2=80=99s value as variable is void: it

while expected result is 1.=C2=A0 Uncompiled code works as expected.

TIA,

Michael.
--00000000000089b44205d13b4052-- From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 17:05:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Paul Pogonyshev Cc: Michael Heerdegen , Stefan Monnier , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163742785314995 (code B ref 51982); Sat, 20 Nov 2021 17:05:03 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 17:04:13 +0000 Received: from localhost ([127.0.0.1]:43586 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moTmf-0003tm-9c for submit@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 ) id 1moTmc-0003tX-7h for 51982@debbugs.gnu.org; Sat, 20 Nov 2021 12:04:11 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: Date: Sat, 20 Nov 2021 18:04:04 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> References: <87y25jo2q1.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 20 nov. 2021 kl. 17.54 skrev Paul Pogonyshev : > 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. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Paul Pogonyshev Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 17:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , Stefan Monnier , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163742898325662 (code B ref 51982); Sat, 20 Nov 2021 17:24:02 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 17:23:03 +0000 Received: from localhost ([127.0.0.1]:43631 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moU4t-0006fq-0G for submit@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 ) id 1moU4q-0006f6-Ae for 51982@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@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: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> In-Reply-To: <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> From: Paul Pogonyshev Date: Sat, 20 Nov 2021 18:22:43 +0100 Message-ID: Content-Type: multipart/alternative; boundary="0000000000005c653f05d13ba42c" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 wro= te: > 20 nov. 2021 kl. 17.54 skrev Paul Pogonyshev : > > > 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
> 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@acm.org> wrote:
20 nov. 2021 kl. 17.54 skrev Paul Pogo= nyshev <pogony= shev@gmail.com>:

> I consider this bug pretty important.

You are not alone! However, it'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.

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

--0000000000005c653f05d13ba42c-- From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 18:35:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Paul Pogonyshev Cc: Michael Heerdegen , Stefan Monnier , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.16374332569627 (code B ref 51982); Sat, 20 Nov 2021 18:35:01 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 18:34:16 +0000 Received: from localhost ([127.0.0.1]:43660 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moVBn-0002VD-QE for submit@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 ) id 1moVBi-0002Uu-73 for 51982@debbugs.gnu.org; Sat, 20 Nov 2021 13:34:14 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Message-Id: 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\)) Date: Sat, 20 Nov 2021 19:34:03 +0100 In-Reply-To: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 : > > 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-- From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Paul Pogonyshev Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 20:54:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , Stefan Monnier , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163744160227750 (code B ref 51982); Sat, 20 Nov 2021 20:54:01 +0000 Received: (at 51982) by debbugs.gnu.org; 20 Nov 2021 20:53:22 +0000 Received: from localhost ([127.0.0.1]:43744 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moXMQ-0007DW-65 for submit@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 ) id 1moXMM-0007DD-Gp for 51982@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@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: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> In-Reply-To: From: Paul Pogonyshev Date: Sat, 20 Nov 2021 21:53:01 +0100 Message-ID: Content-Type: multipart/alternative; boundary="00000000000075852505d13e9494" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 wro= te: > 20 nov. 2021 kl. 18.22 skrev Paul Pogonyshev : > > > > 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
Thanks for the fix. I'm sure in 2025 it will be releas= ed.

On Sat, 20 Nov 2021 at 19:34, Mattias Engdeg=C3=A5rd <mattiase@acm.org> wrote:
20 nov. 2021 kl. 18.22 skrev Paul Pogo= nyshev <pogony= shev@gmail.com>:

> > 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 str= ict that even a *fix* cannot go in? Unless it is going to be a rewrite of h= alf 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 s= atisfied 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.<= br>
--00000000000075852505d13e9494-- From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Michael Heerdegen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 21 Nov 2021 08:00:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Paul Pogonyshev Cc: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , Stefan Monnier , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163748159410172 (code B ref 51982); Sun, 21 Nov 2021 08:00:02 +0000 Received: (at 51982) by debbugs.gnu.org; 21 Nov 2021 07:59:54 +0000 Received: from localhost ([127.0.0.1]:44058 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mohlR-0002dz-Qk for submit@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 ) id 1mohlP-0002dd-La for 51982@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 References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> Date: Sun, 21 Nov 2021 08:59:34 +0100 In-Reply-To: (Paul Pogonyshev's message of "Sat, 20 Nov 2021 18:22:43 +0100") Message-ID: <87wnl23pnd.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Paul Pogonyshev 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. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 21 Nov 2021 10:00:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Michael Heerdegen Cc: Paul Pogonyshev , 51982@debbugs.gnu.org, Stefan Monnier Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.16374887697381 (code B ref 51982); Sun, 21 Nov 2021 10:00:02 +0000 Received: (at 51982) by debbugs.gnu.org; 21 Nov 2021 09:59:29 +0000 Received: from localhost ([127.0.0.1]:44263 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mojdB-0001uy-Bj for submit@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 ) id 1mojd8-0001uc-EQ for 51982@debbugs.gnu.org; Sun, 21 Nov 2021 04:59:28 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <87wnl23pnd.fsf@web.de> Date: Sun, 21 Nov 2021 10:59:15 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) 21 nov. 2021 kl. 08.59 skrev Michael Heerdegen = : > 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). From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Michael Heerdegen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 22 Nov 2021 10:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Paul Pogonyshev , 51982@debbugs.gnu.org, Stefan Monnier Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.16375769853735 (code B ref 51982); Mon, 22 Nov 2021 10:30:02 +0000 Received: (at 51982) by debbugs.gnu.org; 22 Nov 2021 10:29:45 +0000 Received: from localhost ([127.0.0.1]:47023 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mp6Zt-0000y1-J8 for submit@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 ) id 1mp6Zo-0000xm-U3 for 51982@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 References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> Date: Mon, 22 Nov 2021 11:29:08 +0100 In-Reply-To: <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> ("Mattias =?UTF-8?Q?Engdeg=C3=A5rd?="'s message of "Sun, 21 Nov 2021 10:59:15 +0100") Message-ID: <877dd0bi17.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Mattias Engdeg=C3=A5rd 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. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 22 Nov 2021 13:57:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Michael Heerdegen Cc: Paul Pogonyshev , 51982@debbugs.gnu.org, Stefan Monnier Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163758940226770 (code B ref 51982); Mon, 22 Nov 2021 13:57:01 +0000 Received: (at 51982) by debbugs.gnu.org; 22 Nov 2021 13:56:42 +0000 Received: from localhost ([127.0.0.1]:47274 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mp9oH-0006xi-UR for submit@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 ) id 1mp9oE-0006xB-4F for 51982@debbugs.gnu.org; Mon, 22 Nov 2021 08:56:41 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <877dd0bi17.fsf@web.de> Date: Mon, 22 Nov 2021 14:56:27 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> 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 : > 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 22 nov. 2021 kl. 11.29 skrev Michael Heerdegen = : > 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. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 22 Nov 2021 17:36:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Michael Heerdegen Cc: Paul Pogonyshev , 51982@debbugs.gnu.org, Stefan Monnier Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163760254027151 (code B ref 51982); Mon, 22 Nov 2021 17:36:03 +0000 Received: (at 51982) by debbugs.gnu.org; 22 Nov 2021 17:35:40 +0000 Received: from localhost ([127.0.0.1]:48998 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mpDEB-00073o-41 for submit@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 ) id 1mpDE4-00073P-Dd for 51982@debbugs.gnu.org; Mon, 22 Nov 2021 12:35:37 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Message-Id: 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\)) Date: Mon, 22 Nov 2021 18:35:18 +0100 In-Reply-To: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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= =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= =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-- From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 25 04:28:53 2021 Received: (at control) by debbugs.gnu.org; 25 Nov 2021 09:28:53 +0000 Received: from localhost ([127.0.0.1]:55774 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mqB3l-0005Hn-1i for submit@debbugs.gnu.org; Thu, 25 Nov 2021 04:28:53 -0500 Received: from mail18c50.megamailservers.eu ([91.136.10.28]:49190) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mqB3j-0005He-3n for control@debbugs.gnu.org; Thu, 25 Nov 2021 04:28:51 -0500 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1637832529; bh=rBaIOngm6b5nBv3XUibUMU9qgJXllUtedFyD4sr/El4=; h=From:Subject:Date:To:From; b=PVz5a7ND854ZptgV8BLORLA2aF7rbwxnHmvJTVgEUqbFc8eAFnpDtSaVWWv5iaBxT 8ji7CKuo7OUsUEOdjIOdsGfZjlRq/zjae0hWLza0lv39NkkdXFi9Vf3X/WO3KFyJ35 MeCJoh7i65VM2L03pdQlVAbTVwiW54xLthizr0cE= Feedback-ID: mattiase@acm.or Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se [83.227.82.185]) (authenticated bits=0) by mail18c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 1AP9Sl1c001802 for ; Thu, 25 Nov 2021 09:28:48 +0000 From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.21\)) Subject: Message-Id: <185C954A-5C37-4D0C-8A91-DD549AB46F50@acm.org> Date: Thu, 25 Nov 2021 10:28:46 +0100 To: control@debbugs.gnu.org X-Mailer: Apple Mail (2.3445.104.21) X-CTCH-RefID: str=0001.0A742F27.619F5751.0003, 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=619f5751 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=jhuKRk7ZlGUUL4rbrk8A:9 a=CjuIK1q_8ugA:10 a=ejaKLpJ7TEwA:10 a=xo5jKAKm-U-Zyk2_beg_:22 X-Origin-Country: SE X-Spam-Score: 3.0 (+++) 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: tags 51982 patch stop Content analysis details: (3.0 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) 2.0 BLANK_SUBJECT Subject is present but empty X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 2.0 (++) 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: tags 51982 patch stop Content analysis details: (2.0 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) 2.0 BLANK_SUBJECT Subject is present but empty -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager tags 51982 patch stop From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 30 Nov 2021 14:13:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , Paul Pogonyshev , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163828155318798 (code B ref 51982); Tue, 30 Nov 2021 14:13:01 +0000 Received: (at 51982) by debbugs.gnu.org; 30 Nov 2021 14:12:33 +0000 Received: from localhost ([127.0.0.1]:40465 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ms3s1-0004t7-2v for submit@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 ) id 1ms3ry-0004sr-AU for 51982@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 Message-ID: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> Date: Tue, 30 Nov 2021 09:12:20 -0500 In-Reply-To: ("Mattias =?UTF-8?Q?Engdeg=C3=A5rd?="'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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 30 Nov 2021 17:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Stefan Monnier Cc: Michael Heerdegen , Paul Pogonyshev , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163829172716432 (code B ref 51982); Tue, 30 Nov 2021 17:03:02 +0000 Received: (at 51982) by debbugs.gnu.org; 30 Nov 2021 17:02:07 +0000 Received: from localhost ([127.0.0.1]:42275 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ms6W7-0004Gy-82 for submit@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 ) id 1ms6W4-0004Gl-UX for 51982@debbugs.gnu.org; Tue, 30 Nov 2021 12:02:06 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Message-Id: 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\)) Date: Tue, 30 Nov 2021 18:01:59 +0100 In-Reply-To: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 : > 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= =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= =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-- From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 30 Nov 2021 22:43:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , Paul Pogonyshev , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.16383121243720 (code B ref 51982); Tue, 30 Nov 2021 22:43:01 +0000 Received: (at 51982) by debbugs.gnu.org; 30 Nov 2021 22:42:04 +0000 Received: from localhost ([127.0.0.1]:42762 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1msBp5-0000xw-Ng for submit@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 ) id 1msBp3-0000xP-7U for 51982@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 Message-ID: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> Date: Tue, 30 Nov 2021 17:41:51 -0500 In-Reply-To: ("Mattias =?UTF-8?Q?Engdeg=C3=A5rd?="'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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 01 Dec 2021 16:05:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Stefan Monnier Cc: Michael Heerdegen , Paul Pogonyshev , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163837469830199 (code B ref 51982); Wed, 01 Dec 2021 16:05:02 +0000 Received: (at 51982) by debbugs.gnu.org; 1 Dec 2021 16:04:58 +0000 Received: from localhost ([127.0.0.1]:45328 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1msS6M-0007r0-61 for submit@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 ) id 1msS6J-0007qj-0X for 51982@debbugs.gnu.org; Wed, 01 Dec 2021 11:04:56 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: Date: Wed, 1 Dec 2021 17:04:44 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) 30 nov. 2021 kl. 23.41 skrev Stefan Monnier : > [ 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! From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 01 Dec 2021 18:35:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , Paul Pogonyshev , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163838365221621 (code B ref 51982); Wed, 01 Dec 2021 18:35:02 +0000 Received: (at 51982) by debbugs.gnu.org; 1 Dec 2021 18:34:12 +0000 Received: from localhost ([127.0.0.1]:45601 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1msUQm-0005ce-Dg for submit@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 ) id 1msUQk-0005cR-SI for 51982@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 Message-ID: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> Date: Wed, 01 Dec 2021 13:34:01 -0500 In-Reply-To: ("Mattias =?UTF-8?Q?Engdeg=C3=A5rd?="'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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 01 Dec 2021 22:33:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Stefan Monnier Cc: Michael Heerdegen , Paul Pogonyshev , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163839797732656 (code B ref 51982); Wed, 01 Dec 2021 22:33:01 +0000 Received: (at 51982) by debbugs.gnu.org; 1 Dec 2021 22:32:57 +0000 Received: from localhost ([127.0.0.1]:46025 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1msY9p-0008Ue-Jp for submit@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 ) id 1msY9n-0008UR-EC for 51982@debbugs.gnu.org; Wed, 01 Dec 2021 17:32:56 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: Date: Wed, 1 Dec 2021 23:32:49 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: <6EA55EF4-D5B2-490E-B1FF-DC86A034C893@acm.org> References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> 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 : >>> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 1 dec. 2021 kl. 19.34 skrev Stefan Monnier : >>> 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! From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 02 Dec 2021 09:14:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Stefan Monnier Cc: Michael Heerdegen , Paul Pogonyshev , 51982@debbugs.gnu.org Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.163843642525908 (code B ref 51982); Thu, 02 Dec 2021 09:14:02 +0000 Received: (at 51982) by debbugs.gnu.org; 2 Dec 2021 09:13:45 +0000 Received: from localhost ([127.0.0.1]:46561 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1msi9x-0006jn-Et for submit@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 ) id 1msi9v-0006jY-80 for 51982@debbugs.gnu.org; Thu, 02 Dec 2021 04:13:44 -0500 X-Authenticated-User: mattiase@bredband.net 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@acm.or 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\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <6EA55EF4-D5B2-490E-B1FF-DC86A034C893@acm.org> Date: Thu, 2 Dec 2021 10:13:31 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> <6EA55EF4-D5B2-490E-B1FF-DC86A034C893@acm.org> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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. From unknown Sat Jun 14 03:54:57 2025 X-Loop: help-debbugs@gnu.org Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas Resent-From: Lars Ingebrigtsen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 09 Sep 2022 18:00:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51982 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , Stefan Monnier , 51982@debbugs.gnu.org, Paul Pogonyshev Received: via spool by 51982-submit@debbugs.gnu.org id=B51982.166274639431250 (code B ref 51982); Fri, 09 Sep 2022 18:00:02 +0000 Received: (at 51982) by debbugs.gnu.org; 9 Sep 2022 17:59:54 +0000 Received: from localhost ([127.0.0.1]:35383 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oWiHz-00087X-0z for submit@debbugs.gnu.org; Fri, 09 Sep 2022 13:59:54 -0400 Received: from quimby.gnus.org ([95.216.78.240]:48342) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oWiHx-00087J-43 for 51982@debbugs.gnu.org; Fri, 09 Sep 2022 13:59:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID :Date:References:In-Reply-To:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=8WFqwpmL4m33ghDIofl/qrb+m4uGkYHQo2hX0sThgzE=; b=quVI+G2IT9o3mltMn/X8Hlj5KI Wc5FqMIHM/oRQaXxuwRvDzjtVOY11XdSvlAeFYAcZ3ETZWh/wpgiH15jlMWLxcDde2l936f2QO2hq xIwlTtDx+wfi013W09MDmZHve41axOBFtFMMzvi47/2PMJMsz6URSIes7sdrHRTU56oI=; Received: from [84.212.220.105] (helo=joga) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oWiHn-0001DC-FC; Fri, 09 Sep 2022 19:59:29 +0200 From: Lars Ingebrigtsen In-Reply-To: ("Mattias =?UTF-8?Q?Engdeg=C3=A5rd?="'s message of "Thu, 2 Dec 2021 10:13:31 +0100") References: <87y25jo2q1.fsf@web.de> <29C3A3F8-CD9F-4AF2-A731-3304FC30E380@acm.org> <87wnl23pnd.fsf@web.de> <59A729EF-C4D4-47EB-9ADC-19FE8EBE7F10@acm.org> <877dd0bi17.fsf@web.de> <6EA55EF4-D5B2-490E-B1FF-DC86A034C893@acm.org> X-Now-Playing: Supertramp's _Breakfast in America_: "Child of Vision" Date: Fri, 09 Sep 2022 19:59:23 +0200 Message-ID: <878rmston8.fsf@gnus.org> 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-Report: Spam detection software, running on the system "quimby.gnus.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 @@CONTACT_ADDRESS@@ for details. Content preview: Skimming this bug report, it seems like the proposed patch was pushed as: commit 45252ad8f932c98a373ef0ab7f3363a3e27ccbe4 Author: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= AuthorDate: Mon Nov 22 16:56:38 2021 +0100 Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Skimming this bug report, it seems like the proposed patch was pushed as: commit 45252ad8f932c98a373ef0ab7f3363a3e27ccbe4 Author: Mattias Engdeg=C3=A5rd AuthorDate: Mon Nov 22 16:56:38 2021 +0100 Fix closure-conversion of shadowed captured lambda-lifted vars If I'm skimming the rest of the thread correctly, there wasn't anything further to do here, so I'm closing this bug report. If I misunderstood, please respond to the debbugs address and we'll reopen. From debbugs-submit-bounces@debbugs.gnu.org Fri Sep 09 13:59:54 2022 Received: (at control) by debbugs.gnu.org; 9 Sep 2022 17:59:54 +0000 Received: from localhost ([127.0.0.1]:35386 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oWiIE-00087z-5c for submit@debbugs.gnu.org; Fri, 09 Sep 2022 13:59:54 -0400 Received: from quimby.gnus.org ([95.216.78.240]:48362) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oWiI0-00087N-MW for control@debbugs.gnu.org; Fri, 09 Sep 2022 13:59:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Subject:From:To:Message-Id:Date:Sender:Reply-To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=LZy70AeV9qvpMHU0VOMZilAqZDeXd9xypYBpOfnpSPg=; b=lSlrCTzN4sJrcG6vP5ay/ZSCLJ EodL2AVxgsZXHg7Bh5UN5m+DL+hyC3AdfEWEMr6xLgLC7PN/HXsFgMiKi8ryOylu2Flw/15dPnp/m K5gUAdnQu9XUpJWQd43WdDY+QcaTkvhe3+6U4ck23HQRP7X9gVuyVHS+/gt6CuJiSzKE=; Received: from [84.212.220.105] (helo=joga) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oWiHs-0001DP-V9 for control@debbugs.gnu.org; Fri, 09 Sep 2022 19:59:34 +0200 Date: Fri, 09 Sep 2022 19:59:32 +0200 Message-Id: <877d2ctomz.fsf@gnus.org> To: control@debbugs.gnu.org From: Lars Ingebrigtsen Subject: control message for bug #51982 X-Spam-Report: Spam detection software, running on the system "quimby.gnus.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 @@CONTACT_ADDRESS@@ for details. Content preview: close 51982 29.1 quit Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) close 51982 29.1 quit