summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/edebug.el
diff options
context:
space:
mode:
authorPhilipp Stephani <phst@google.com>2021-03-18 12:40:08 +0100
committerPhilipp Stephani <phst@google.com>2021-04-10 18:19:49 +0200
commit53dfd85a7f971875e716a55f010ee508bce89eed (patch)
tree3eb0b220ff838287f4d6cd3cd45d19794aceecf7 /lisp/emacs-lisp/edebug.el
parentb72571ca49dd16be174f02ed14b460c136c9aaf2 (diff)
downloademacs-53dfd85a7f971875e716a55f010ee508bce89eed.tar.gz
emacs-53dfd85a7f971875e716a55f010ee508bce89eed.tar.bz2
emacs-53dfd85a7f971875e716a55f010ee508bce89eed.zip
Edebug: Disable backtracking when hitting a &define keyword.
Edebug doesn't deal well with backtracking out of definitions, see Bug#41988. Rather than trying to support this rare situation (e.g. by implementing a multipass parser), prevent it by adding an implicit gate. * lisp/emacs-lisp/edebug.el (edebug--match-&-spec-op): Disable backtracking when hitting a &define keyword. * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-duplicate-&define): New unit test. (edebug-tests--duplicate-&define): New helper macro. * doc/lispref/edebug.texi (Backtracking): Mention &define in the list of constructs that disable backtracking. * etc/NEWS: Document new behavior.
Diffstat (limited to 'lisp/emacs-lisp/edebug.el')
-rw-r--r--lisp/emacs-lisp/edebug.el18
1 files changed, 10 insertions, 8 deletions
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index f1455ffe73b..365bc748741 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -1942,14 +1942,16 @@ a sequence of elements."
;; Normally, &define is interpreted specially other places.
;; This should only be called inside of a spec list to match the remainder
;; of the current list. e.g. ("lambda" &define args def-body)
- (edebug-make-form-wrapper
- cursor
- (edebug-before-offset cursor)
- ;; Find the last offset in the list.
- (let ((offsets (edebug-cursor-offsets cursor)))
- (while (consp offsets) (setq offsets (cdr offsets)))
- offsets)
- specs))
+ (prog1 (edebug-make-form-wrapper
+ cursor
+ (edebug-before-offset cursor)
+ ;; Find the last offset in the list.
+ (let ((offsets (edebug-cursor-offsets cursor)))
+ (while (consp offsets) (setq offsets (cdr offsets)))
+ offsets)
+ specs)
+ ;; Stop backtracking here (Bug#41988).
+ (setq edebug-gate t)))
(cl-defmethod edebug--match-&-spec-op ((_ (eql &name)) cursor specs)
"Compute the name for `&name SPEC FUN` spec operator.