Subject: Re: bug#46818: leim bootstrap: Variable binding depth exceeds max-specpdl-size

From: Stefan Monnier <[email-masked]>
Date: Sat, 27 Feb 2021 19:02:13 -0500

>>> I see them with 'make bootstrap', and I think they started with:
>>> * lisp/emacs-lisp/cconv.el: Improve line-nb info of unused var warnings
>>> a350ae058c 2021-02-26 20:24:52 -0500
>>> https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=a350ae058caedcb7be7d332564817954e3624e60
>>
>> I can't reproduce it here, neither with `make bootstrap` nor after `make
>> extraclean`.  Any chance that a5ad6747c9da238bd2bcd335b9744ce9f4972ff1
>> fixed it?
> Oh, wait, no, I see it now, so it's clearly not fixed,

It's a fleeting thing, fairly delicate to catch.
I can now reproduce it and it seems that it's just a "slightly too deep"
recursion when `quail-update-leim-list-file` calls `find-file-noselect`
which ends up loading `vc-git` which in turn loads `diff-mode` and
where the macroexpansion of some pcase macros hits the limit.

I suspect (but have not been able to confirm) that it might be due to the
change in `pcase--if` where we now return `(progn (ignore ,test) ,then)`
instead of just `then`, which causes the macroexpansion of `pcase-let`s
to be slightly more deeply nested.

Then again, I had to increase max_specpdl_size from 1600 to 1740 to get
past that problem, which seems like a higher impact than what I expect
from this little change in `pcase--if`.

In any case, rather than bump the pdl limit, I suggest the patch below,
which completely avoids the need to macroexpand all that code we won't
be using anyway.

        Stefan

diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index e4bdf50f52..a3685b564d 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -1312,8 +1312,13 @@ update-leim-list-functions
 
 (defun update-leim-list-file (&rest dirs)
   "Update LEIM list file in directories DIRS."
-  (dolist (function update-leim-list-functions)
-    (apply function dirs)))
+  ;; bug#46818: This `let'-binding is not indispensable, but
+  ;; it reduces the recursion depth during bootstrap (at which
+  ;; point some of the core ELisp files haven't been byte-compiled
+  ;; yet, which causes deeper-than-normal recursion).
+  (let ((vc-handled-backends nil))
+    (dolist (function update-leim-list-functions)
+      (apply function dirs))))
 
 (defvar-local current-input-method nil
   "The current input method for multilingual text.