Output better error messages on certain edebug spec errors

This fixes bug#65620.  The error thrown up to now was "Void
function edebug-after".  This has been replaced by "Invalid
call to `edebug-before'.  Is the edebug spec for `foo'
correct?".

* lisp/emacs-lisp/edebug.el (edebug-b/a-error): New function
which throws the new friendlier error message.
(edebug-before, edebug-after): Replace the defalias's to nil
with actual functions which just call edebug-b/a-error.

* doc/lispref/edebug.texi (Specification List): In the entry
for `sexp', warn against mistakenly using `form' for an
This commit is contained in:
Alan Mackenzie 2023-09-02 13:50:03 +00:00
parent 338be4ff7d
commit 1d46bca1c9
2 changed files with 46 additions and 4 deletions

View file

@ -1289,6 +1289,8 @@ examples):
@item sexp
A single unevaluated Lisp object, which is not instrumented.
@c an "expression" is not necessarily intended for evaluation.
If the macro evaluates an argument at macro-expansion time, you should
use @code{sexp} for it rather than @code{form}.
@item form
A single evaluated expression, which is instrumented. If your macro

View file

@ -2469,12 +2469,52 @@ MSG is printed after `::::} '."
(setf (cdr (assq 'edebug edebug-behavior-alist))
'(edebug-default-enter edebug-fast-before edebug-fast-after)))
(defalias 'edebug-before nil
;; The following versions of `edebug-before' and `edebug-after' exist
;; to handle the error which occurs if either of them gets called
;; without an enclosing `edebug-enter'. This can happen, for example,
;; when a macro mistakenly has a `form' element in its edebug spec,
;; and it additionally, at macro-expansion time, calls `eval',
;; `apply', or `funcall' (etc.) on the corresponding argument. This
;; is intended to fix bug#65620.
(defun edebug-b/a-error (func)
"Throw an error for an invalid call of FUNC.
FUNC is expected to be `edebug-before' or `edebug-after'."
(let (this-macro
(n 0)
bt-frame)
(while (and (setq bt-frame (backtrace-frame n))
(not (and (car bt-frame)
(memq (cadr bt-frame)
'(macroexpand macroexpand-1)))))
(setq n (1+ n)))
(when bt-frame
(setq this-macro (caaddr bt-frame)))
(error
(concat "Invalid call to `" (symbol-name func) "'"
(if this-macro
(concat ". Is the edebug spec for `"
(symbol-name this-macro)
"' correct?")
"" ; Not sure this case is possible (ACM, 2023-09-02)
)))))
(defun edebug-before (_before-index)
"Function called by Edebug before a form is evaluated.
See `edebug-behavior-alist' for implementations.")
(defalias 'edebug-after nil
See `edebug-behavior-alist' for other implementations. This
version of `edebug-before' gets called when edebug is not yet set
up. `edebug-enter' binds the function cell to a real function
when edebug becomes active."
(edebug-b/a-error 'edebug-before))
(defun edebug-after (_before-index _after-index _form)
"Function called by Edebug after a form is evaluated.
See `edebug-behavior-alist' for implementations.")
See `edebug-behavior-alist' for other implementations. This
version of `edebug-after' gets called when edebug is not yet set
up. `edebug-enter' binds the function cell to a real function
when edebug becomes active."
(edebug-b/a-error 'edebug-after))
(defun edebug--update-coverage (after-index value)
(let ((old-result (aref edebug-coverage after-index)))