Subject: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change

From: Stephen Berman <[email-masked]>
Date: Thu, 29 May 2025 00:58:22 +0200

On Wed, 28 May 2025 21:28:22 +0300 Eli Zaretskii <[email-masked]> wrote:

>> From: Stefan Monnier <[email-masked]>
>> Cc: [email-masked],  [email-masked]
>> Date: Wed, 28 May 2025 12:59:52 -0400
>> 
>> >>  * Incompatible Lisp Changes in Emacs 31.1
>> >>  
>> >> +** 'setq-local' computes the value before making the variable local.
>> >> +The previous code made the variable buffer local before
>> >> +computing the value to assign to it.
>> >> +This bug fix is a subtle change to the semantics which should make
>> >> +no difference to the vast majority of uses but can occasionally affect
>> >> +code in surprising ways if the computation of the value refers to the
>> >> +variable.
>> >
>> > I think this should describe the case upon which Stephen stumbled:
>> > code which uses setq-local inside a let-binding (perhaps an implicit
>> > one, such as the one the various with-SOMETHING macros do), and
>> > expects the buffer-local value to stay after the let-binding is
>> > exited.
>> 
>> Maybe you should write it, then because you seem to understand that case
>> better than I (I did look at the code to try and figure out what was the
>> specific origin of the problem but .. failed).  But note that it's only
>> one case that can be affected, there are others.
>
> Stephen, would you mind explaining in more detail what in that commit
> caused the regression on the master branch?  I'd like us all to be on
> the same page before we decide how (and whether) to document it.

Unfortunately, I have been unable to step through `setq-local' with
Edebug when the variable `todo-categories' gets set; typing `i' just
returns me to todo-read-category after the variable gets set.  So I only
see what I reported in the bug report, which I repeat here for
convenience:

"Th[e] difference between emacs-30 and master manifests itself in the
function `todo-category-completions' (called from `todo-read-category')
around the following code:

(with-current-buffer (find-file-noselect f 'nowarn)
  [...]
  (todo-mode)
  [...])

In both master and emacs-30, before entering this sexp, the buffer-local
value of `todo-categories' is nil, but after invoking `todo-mode' its
value (for the buffer visiting the Todo file `f') becomes non-nil.
After leaving the `with-current-buffer' form, `todo-categories' retains
its non-nil value in master, but reverts to nil in emacs-30.  The mode
function `todo-mode' calls `todo-modes-set-3', which contains the form
`(setq-local todo-categories (todo-set-categories))'.  This led me to
commit f3e0bdf1b98, and indeed, when I undo that change in master, the
problematic prompt on calling `todo-jump-to-category' does not happen."

Can either of you tell me how to debug `setq-local' or what to look for
in the `with-current-buffer' form to try and find the cause of the
difference between master and emacs-30?

Steve Berman