7

On startup I'm getting this message:

Eager macro-expansion failure: (wrong-number-of-arguments (3 . 3) 2)

How can I find whats causing the warning? --debug-init doesn't do anything in this case as it does with many other errors.

6
  • 1
    You find internal-macroexpand-for-load in macroexp.el. You could copy the code to the beginning of your init-file (maybe early-init file) and include the form argument and the load file in the message string, i.e., (message "Eager macro-expansion failure: %S form: %S load file: %S" err form load-file-name). Maybe that helps to identify the problem.
    – Tobias
    Commented Dec 19, 2019 at 15:07
  • If starting Emacs using emacs -Q doesn't show the problem then blame your init file. The easiest approach to finding a problem in your init file is to bisect your init file. That's a binary search - very quick to do.
    – Drew
    Commented Dec 19, 2019 at 15:41
  • @Drew It depends on the situation whether bisection is really the best way to go. My init file ~/.emacs loads 60 files ~/.emacs.d/[0-9][0-9]*.el. That does not include the libraries that are loaded from those. I've got some mechanism that allows me to select just a bunch of those files if I have problems. Even so this is not enjoyable and a direct hint on what goes wrong is really nice.
    – Tobias
    Commented Dec 19, 2019 at 20:45
  • 2
    @Tobias: OP wants to trace eager macroexpansion - a legitimate aim/question in its own right. Not necessarily the quickest way to solve the given wrong-args problem, but good to know - a good question - in any case.
    – Drew
    Commented Dec 19, 2019 at 21:03
  • 1
    @Drew You said: "Unless, of course, you already have a good idea where the problem likely lies." My first comment aims at getting more information for building up that "good idea". You are clearly right that if the occurrence probability is evenly distributed over the full domain then bisection is the best approach.
    – Tobias
    Commented Dec 19, 2019 at 21:14

1 Answer 1

2

This error message comes from the macroexp.el function, internal-macroexpand-for-load. It should go a little something like this (I have simplified the t portion of a cond, where most code will end up):

    (condition-case err
        (let ((macroexp--pending-eager-loads
               (cons load-file-name macroexp--pending-eager-loads)))
          (if full-p
              (macroexpand-all form)
            (macroexpand form)))
      (error
       ;; Hopefully this shouldn't happen thanks to the cycle detection,
       ;; but in case it does happen, let's catch the error and give the
       ;; code a chance to macro-expand later.
       (message "Eager macro-expansion failure: %S" err)
       form))

As you can see, it essentially swallows up the error. It's pretty hard to get at this, since the function will simply note the problem, eat the error, and return the original form. There is hope, though: debug-on-signal plus debug-on-error.

The error message you showed indicates that err in this condition-case is a signal: wrong-number-of-arguments. So if we instruct Emacs to first debug on any errors (by doing something like (setq debug-on-error t)), and then on any signal (with (setq debug-on-signal t)), we end up getting into the debugger with the stack trace ready to examine. If you don't mark debug-on-error, nothing will happen, so you need to have bot set to t.

FWIW, I reproduced the behavior you mentioned with this obviously wrong code:

(defun bad-defun (str)
  (rx (eval (substring str 1))))

...and M-x evaluate-buffer, then observed that I got a stack trace after executing M-: (setq debug-on-signal t) and M-: (setq debug-on-error t), so some similar combination may work for you. Perhaps setting it at the top of your initialization file, or passing it on the Emacs command line.

Caveat: Once you encounter the error, you should probably turn off debug-on-signal, because it will pop up when you are in the middle of something, any time a function reports an error or warning!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.