GNU bug report logs -
#75498
31.0.50; cl-block is not lexically scoped
Previous Next
Reported by: Ihor Radchenko <yantar92 <at> posteo.net>
Date: Sat, 11 Jan 2025 16:09:01 UTC
Severity: normal
Found in version 31.0.50
Done: Stefan Monnier <monnier <at> iro.umontreal.ca>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 75498 in the body.
You can then email your comments to 75498 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Sat, 11 Jan 2025 16:09:01 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Ihor Radchenko <yantar92 <at> posteo.net>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Sat, 11 Jan 2025 16:09:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
According to the docstring, `cl-block' should be lexically scoped:
Code inside the BODY forms can call cl-return-from
to jump prematurely out of the block. This differs from catch and throw
in two respects: First, the NAME is an unevaluated symbol rather than a
quoted symbol or other form; and second, NAME is lexically rather than
dynamically scoped: Only references to it within BODY will work. These
references may appear inside macro expansions, but not inside functions
called from BODY.
But try the following reproducer:
1. create file test.el
;; -*- lexical-binding: t; -*-
(defun return-from-x ()
(cl-return-from x 'dynamic))
(defun x-block ()
(cl-block x
(return-from-x)
(cl-return-from x 'lexical)))
2. (load "/path/to/test.el)
3. M-: (x-block)
Expected: 'lexical is returned.
Observed: 'dynamic is returned.
In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.42, cairo version 1.18.2) of 2025-01-10 built on localhost
Repository revision: e8deac66adef279a15c806d7547a7610b0189795
Repository branch: scratch/igc
Windowing system distributor 'The X.Org Foundation', version 11.0.12101014
System Description: Gentoo Linux
Configured using:
'configure --with-mps=yes --with-native-compilation 'CFLAGS=-g3
-I/opt/mps/include -L/opt/mps/lib'
JAVAC=/etc/java-config-2/current-system-vm/bin/javac
PKG_CONFIG_PATH=/usr/share/guile-data/3.0/pkgconfig'
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Sat, 11 Jan 2025 16:42:01 GMT)
Full text and
rfc822 format available.
Message #8 received at 75498 <at> debbugs.gnu.org (full text, mbox):
> From: Ihor Radchenko <yantar92 <at> posteo.net>
> Date: Sat, 11 Jan 2025 16:10:39 +0000
>
>
> According to the docstring, `cl-block' should be lexically scoped:
>
> Code inside the BODY forms can call cl-return-from
> to jump prematurely out of the block. This differs from catch and throw
> in two respects: First, the NAME is an unevaluated symbol rather than a
> quoted symbol or other form; and second, NAME is lexically rather than
> dynamically scoped: Only references to it within BODY will work. These
> references may appear inside macro expansions, but not inside functions
> called from BODY.
>
> But try the following reproducer:
>
> 1. create file test.el
>
> ;; -*- lexical-binding: t; -*-
>
> (defun return-from-x ()
> (cl-return-from x 'dynamic))
>
> (defun x-block ()
> (cl-block x
> (return-from-x)
> (cl-return-from x 'lexical)))
>
> 2. (load "/path/to/test.el)
> 3. M-: (x-block)
>
> Expected: 'lexical is returned.
> Observed: 'dynamic is returned.
Adding Stefan.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Wed, 15 Jan 2025 03:40:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 75498 <at> debbugs.gnu.org (full text, mbox):
>> According to the docstring, `cl-block' should be lexically scoped:
>>
>> Code inside the BODY forms can call cl-return-from
>> to jump prematurely out of the block. This differs from catch and throw
>> in two respects: First, the NAME is an unevaluated symbol rather than a
>> quoted symbol or other form; and second, NAME is lexically rather than
>> dynamically scoped: Only references to it within BODY will work. These
>> references may appear inside macro expansions, but not inside functions
>> called from BODY.
Not sure what I was thinking when I wrote that code.
IIRC someone else reported basically this bug already some years ago,
and I lost track of it somehow.
I think the patch below might do the trick.
Stefan
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 01e7b35cc52..7559c58e77a 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -901,9 +901,13 @@ cl-block
called from BODY."
(declare (indent 1) (debug (symbolp body)))
(if (cl--safe-expr-p `(progn ,@body)) `(progn ,@body)
- `(cl--block-wrapper
- (catch ',(intern (format "--cl-block-%s--" name))
- ,@body))))
+ (let ((var (intern (format "--cl-block-%s--" name))))
+ `(cl--block-wrapper
+ ;; Build a unique "tag" in the form of a fresh cons.
+ ;; We include `var' in the cons, just in case it help debugging.
+ (let ((,var (cons ',var nil)))
+ (catch ,var
+ ,@body))))))
;;;###autoload
(defmacro cl-return (&optional result)
@@ -921,7 +925,7 @@ cl-return-from
`defmacro' do not create implicit blocks as they do in Common Lisp."
(declare (indent 1) (debug (symbolp &optional form)))
(let ((name2 (intern (format "--cl-block-%s--" name))))
- `(cl--block-throw ',name2 ,result)))
+ `(cl--block-throw ,name2 ,result)))
;;; The "cl-loop" macro.
@@ -3672,20 +3676,24 @@ cl-compiler-macroexpand
(defvar cl--active-block-names nil)
-(cl-define-compiler-macro cl--block-wrapper (cl-form)
- (let* ((cl-entry (cons (nth 1 (nth 1 cl-form)) nil))
- (cl--active-block-names (cons cl-entry cl--active-block-names))
- (cl-body (macroexpand-all ;Performs compiler-macro expansions.
- (macroexp-progn (cddr cl-form))
- macroexpand-all-environment)))
- ;; FIXME: To avoid re-applying macroexpand-all, we'd like to be able
- ;; to indicate that this return value is already fully expanded.
- (if (cdr cl-entry)
- `(catch ,(nth 1 cl-form) ,@(macroexp-unprogn cl-body))
- cl-body)))
+(cl-define-compiler-macro cl--block-wrapper (form)
+ (pcase form
+ (`(let ((,var . ,val)) (catch ,var . ,body))
+ (let* ((cl-entry (cons var nil))
+ (cl--active-block-names (cons cl-entry cl--active-block-names))
+ (cl-body (macroexpand-all ;Performs compiler-macro expansions.
+ (macroexp-progn body)
+ macroexpand-all-environment)))
+ ;; FIXME: To avoid re-applying macroexpand-all, we'd like to be able
+ ;; to indicate that this return value is already fully expanded.
+ (if (cdr cl-entry)
+ `(let ((,var . ,val)) (catch ,var ,@(macroexp-unprogn cl-body)))
+ cl-body)))
+ ;; `form' was somehow mangled, god knows what happened, let's not touch it.
+ (_ form)))
(cl-define-compiler-macro cl--block-throw (cl-tag cl-value)
- (let ((cl-found (assq (nth 1 cl-tag) cl--active-block-names)))
+ (let ((cl-found (and (symbolp cl-tag) (assq cl-tag cl--active-block-names))))
(if cl-found (setcdr cl-found t)))
`(throw ,cl-tag ,cl-value))
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Wed, 15 Jan 2025 13:34:02 GMT)
Full text and
rfc822 format available.
Message #14 received at submit <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of
text editors" <bug-gnu-emacs <at> gnu.org> writes:
> Not sure what I was thinking when I wrote that code.
> IIRC someone else reported basically this bug already some years ago,
> and I lost track of it somehow.
> I think the patch below might do the trick.
Hmm - but there is something wrong, I get
Debugger entered--Lisp error: (void-variable --cl-block-x--)
(throw --cl-block-x-- 'dynamic)
(return-from-x)
(catch --cl-block-x-- (return-from-x) (throw --cl-block-x-- 'lexical))
(let ((--cl-block-x-- (cons '--cl-block-x-- nil))) (catch --cl-block-x-- (return-from-x) (throw --cl-block-x-- 'lexical)))
(x-block)
for the originally posted example.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Wed, 15 Jan 2025 13:34:02 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Wed, 15 Jan 2025 13:41:01 GMT)
Full text and
rfc822 format available.
Message #20 received at 75498 <at> debbugs.gnu.org (full text, mbox):
Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
of text editors" <bug-gnu-emacs <at> gnu.org> writes:
> Debugger entered--Lisp error: (void-variable --cl-block-x--)
Silly me - this is what we wanted.
Has somebody recompiled Emacs with the patch installed and looked for
such new compiler warnings?
Thx,
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Wed, 15 Jan 2025 13:42:02 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Wed, 15 Jan 2025 22:51:02 GMT)
Full text and
rfc822 format available.
Message #26 received at submit <at> debbugs.gnu.org (full text, mbox):
Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
of text editors" <bug-gnu-emacs <at> gnu.org> writes:
> Has somebody recompiled Emacs with the patch installed and looked for
> such new compiler warnings?
I just checked: there are no new compiler warnings when the patch is
installed.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75498
; Package
emacs
.
(Wed, 15 Jan 2025 22:51:02 GMT)
Full text and
rfc822 format available.
Reply sent
to
Stefan Monnier <monnier <at> iro.umontreal.ca>
:
You have taken responsibility.
(Thu, 16 Jan 2025 22:50:01 GMT)
Full text and
rfc822 format available.
Notification sent
to
Ihor Radchenko <yantar92 <at> posteo.net>
:
bug acknowledged by developer.
(Thu, 16 Jan 2025 22:50:01 GMT)
Full text and
rfc822 format available.
Message #34 received at 75498-done <at> debbugs.gnu.org (full text, mbox):
>> Has somebody recompiled Emacs with the patch installed and looked for
>> such new compiler warnings?
> I just checked: there are no new compiler warnings when the patch is
> installed.
Thanks, pushed to `master`.
Stefan
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Fri, 14 Feb 2025 12:24:22 GMT)
Full text and
rfc822 format available.
This bug report was last modified 129 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.