Subject: bug#74090: 31.0.50; Problems with dabbrev-expand

From: Stephen Berman <[email-masked]>
Date: Fri, 29 Nov 2024 16:38:43 +0100

On Fri, 29 Nov 2024 09:51:57 +0200 Juri Linkov <[email-masked]> wrote:

>> I don't remember seeing such backtrace before this change.
>> But now occasionally an error is raised on typing 'M-/':
>>
>> Debugger entered--Lisp error: (error "Selecting deleted buffer")
>>   set-buffer(#<killed buffer>)
>>   (save-current-buffer (set-buffer buf) (if (and (or (eq (current-buffer) dabbrev--last-buffer) ...
>>   dabbrev-expand(nil)
>>   funcall-interactively(dabbrev-expand nil)
>>   command-execute(dabbrev-expand)
>>
>> because can't set the killed buffer 'buf' here:
>>
>>       (with-current-buffer buf
>>         (if (and (or (eq (current-buffer) dabbrev--last-buffer)
>> 		     (null dabbrev--last-buffer)
>>                      (buffer-live-p dabbrev--last-buffer))
>> 	         (numberp dabbrev--last-expansion-location)
>> 	         (and (> dabbrev--last-expansion-location (point))))
>> 	    (setq dabbrev--last-expansion-location
>> 		  (copy-marker dabbrev--last-expansion-location))))
>>
>> It's difficult to debug because the buffer is already killed at this point.
>> But looking at the logic of backtrace, here is a reproducible test case:
>>
>> 0. emacs-29 -Q
>> 1. C-x b foo RET
>> 2. Type: abc SPC abd
>> 3. C-x b *scratch* RET
>> 4. Type: ab M-/
>> 5. C-x k foo RET
>> 6. Type: SPC ab M-/
>
> Sorry, I meant emacs-30, not emacs-29.

Thanks, I can reproduce it.  With the attached patch (against emacs-30)
I don't get the error; instead, at step 6 "ab" expands to "abc", which I
suppose is what's expected, and then typing `M-/' again shows the
message "No further dynamic expansion for ‘ab’ found", which also seems
as expected.  And with the patch, all current dabbrev regression tests
pass with ert-run-tests-batch-and-exit.  Does anyone see a problem with
the patch?

Steve Berman
diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el
index bbe6a64b626..84306fb3ae7 100644
--- a/lisp/dabbrev.el
+++ b/lisp/dabbrev.el
@@ -472,8 +472,10 @@ dabbrev-expand
                     ;; minibuffer.
                     (window-buffer (get-mru-window)))
                    ;; Otherwise, if we found the expansion in another
-                   ;; buffer, use that buffer for further expansions.
-                   (dabbrev--last-buffer-found dabbrev--last-buffer-found)
+                   ;; buffer and that buffer is still live, use that
+                   ;; buffer for further expansions.
+                   ((buffer-live-p dabbrev--last-buffer-found)
+                    dabbrev--last-buffer-found)
                    ;; Otherwise, use the buffer where we invoked
                    ;; dabbrev-expand.
                    (t (current-buffer))))