bug-gnu-emacs
[Top][All Lists]
Advanced

[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?)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]