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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#62419: closed (28.2; Elisp let-bound buffer-local variable and kill-


From: GNU bug Tracking System
Subject: bug#62419: closed (28.2; Elisp let-bound buffer-local variable and kill-local-variable)
Date: Tue, 12 Sep 2023 00:01:04 +0000

Your message dated Mon, 11 Sep 2023 17:00:48 -0700
with message-id 
<CADwFkm=fOpsqkhwf5010f8XqcFV6JNEfJ_6ihuV7iy1hW24awg@mail.gmail.com>
and subject line Re: bug#62419: 28.2; Elisp let-bound buffer-local variable and 
kill-local-variable
has caused the debbugs.gnu.org bug report #62419,
regarding 28.2; Elisp let-bound buffer-local variable and kill-local-variable
to be marked as done.

(If you believe you have received this mail in error, please contact
help-debbugs@gnu.org.)


-- 
62419: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=62419
GNU Bug Tracking System
Contact help-debbugs@gnu.org with problems
--- Begin Message --- Subject: 28.2; Elisp let-bound buffer-local variable and kill-local-variable Date: Fri, 24 Mar 2023 13:37:57 +0000
Hello,

I’m inlining some elisp which has behaviour I find unintuitive.
To view the bug I would run each top-level form with C-x C-e in turn in an 
elisp buffer.
This behaviour may be expected — the manual mentions something related — but I 
believe this is an unintended edge-case.
N.b. the use of `auto-fill-function’ is just for a variable which turns 
buffer-local when set, not as anything related to this particular symbol.
FWIW I believe this behaviour to be the root cause of 
https://github.com/joaotavora/yasnippet/issues/919 (which was closed due to not 
being able to reproduce it).

—————
;; Ensure that `auto-fill-function' has a buffer-local version and a global
;; version.
(setq auto-fill-function 'local-symbol)
(describe-variable 'auto-fill-function)
;; `auto-fill-function' is let-bound in the buffer scope
(let ((auto-fill-function 'temp-symbol))
  ;; Now there is no buffer-local variable for `auto-fill-function', but the
  ;; `let' unwrapping info is still there.
  (kill-local-variable 'auto-fill-function)
  ;; Since the check in the emacs source is
  ;; a) Is there a buffer-local variable.
  ;; b) Is there a let-binding shadowing the current variable.
  ;; Then this `setq' sets the *global* variable.
  (setq auto-fill-function 'other-symbol))
;; Exiting the `let' has special handling to avoid resetting a local variable
;; when the local variable was `let' bound, which means that overall the `setq'
;; set the global variable and the `let' has been lost.
(describe-variable 'auto-fill-function)
—————


I think the final state after having done the above should be:
1) Global value has not changed.
2) Local value has not changed.

While the observed state after the above is:
1) Global value has been set to `other-symbol'.
2) Local value has been removed.

- The `setq` inside the `let` sets the *global* value rather than creating a 
buffer-local variable.
- The `let` on the buffer-local version of the variable is lost.

The manual for `make-variable-buffer-local` — in `(elisp) Creating 
Buffer-Local` — does mention that if a variable is in a `let` binding then a 
`setq` does not create a buffer-local version.
That said, I’m guessing the intention of this behaviour is so a `let` binding 
on a global variable is modified rather than bypassed by a `setq`.
I’d suggest that is not relevant to the above code since the use of 
`kill-local-variable` means the `let` is effectively lost already (e.g. it does 
not get “reset” on an unwind).

I’m attaching the source code hack that I’ve started using to work around this.
I’m not proposing this as a change, just including it for extra context about 
the cause.
I *believe* that the form of the C code around here looks like the special case 
of a forwarded variable not having a buffer-local value but having a 
buffer-local `let` binding could easily have been an oversight rather than 
intention.
(N.b. for this hack I guessed the meanings of the `let` enum values).

Attachment: emacs-patch.diff
Description: Binary data


--- End Message ---
--- Begin Message --- Subject: Re: bug#62419: 28.2; Elisp let-bound buffer-local variable and kill-local-variable Date: Mon, 11 Sep 2023 17:00:48 -0700
Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Just for the record I’ve been running using essentially this patch (but
>> with !=) since you suggested it and have not had any problems.
>
> Thanks for confirming it fixes the problem for you.
> I pushed it to `master` (doesn't seem "obviously safe" enough for `emacs-29`).
>
>> FWIW I also think the change to avoid `let` binding
>> `auto-fill-function` in `normal-mode` is good.
>
> I also pushed it to `master`.

It seems like this issue was fixed, but it was left open in the bug
tracker.  I'm therefore closing it now.

Please remember to close bug reports when they are fixed.


--- End Message ---

reply via email to

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