[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#46387: 28.0.50; Compiled code making a variable dynamic stopped work
From: |
Mattias Engdegård |
Subject: |
bug#46387: 28.0.50; Compiled code making a variable dynamic stopped working |
Date: |
Tue, 9 Feb 2021 11:32:58 +0100 |
8 feb. 2021 kl. 18.29 skrev Michael Heerdegen <michael_heerdegen@web.de>:
> the latest changes in byte-opt.el seem to have broken some of my code.
> It worked since yesterday, and it still works when interpreted, but the
> compiled code raises this error today:
Intereresting, thank you! And sorry about that.
> (with-suppressed-warnings ((lexical date original-date number))
> (defvar date)
> (defvar original-date)
> (defvar number))
There's a lack of clarity regarding the exact semantics of local `defvar`. The
manual says that its effect is confined to the current lexical scope, but what
exactly does that mean?
As it turns out, parts of the implementation have different opinions about
that. As you observed, the recently added optimisation on master takes a strict
syntactic view: even a `progn` is a lexical scope, and
`with-suppressed-warnings` wraps its body in a `progn`; thus your `defvar`
declarations have no effect outside that construct.
However, the interpreter is at the other extreme end and takes a very dynamic
view. For example:
(defun f (x)
(if x (defvar my-var))
(let ((my-var 17))
(do-something)))
Here, whether my-var is a lexical or dynamic variable depends on the argument
x! The compiler unsurprisingly is of more static persuasion but sadly hazy on
the details. For example, the above function is compiled (in Emacs 27) with
my-var lexically bound, but if we say
(defun g ()
(if (= 1 2) (defvar my-var))
(let ((my-var 17))
(do-something)))
then my-var becomes dynamic. Ouch.
While we ponder over the problem, you may try separate with-suppressed-warnings
for each variable. Ie,
(with-suppressed-warnings ((lexical date))
(defvar date))
(with-suppressed-warnings ((lexical original-date))
(defvar original-date))
(with-suppressed-warnings ((lexical number))
(defvar number))
hoping that each single-expression `progn` will rapidly decay into its confined
expression (a defvar) and thus will be syntactically in the right lexical scope.
(Stefan, it looks like your latest Gnus patch may fall in the same trap. Or?)