GNU bug report logs -
#78637
30.1.90; Calling setopt during init loads cus-start over and over
Previous Next
Full log
Message #14 received at 78637 <at> debbugs.gnu.org (full text, mbox):
> From: Aaron Zeng <azeng <at> janestreet.com>
> Date: Fri, 30 May 2025 11:27:44 -0400
> Cc: 78637 <at> debbugs.gnu.org, app-emacs-dev <at> janestreet.com
>
> On Fri, May 30, 2025 at 3:24 AM Eli Zaretskii <eliz <at> gnu.org> wrote:
> >
> > I don't understand: cus-start is preloaded (see lisp/loadup.el), so
> > "(require 'cus-start)" should be (almost) a no-op. Do you have any
> > evidence that cus-start.el is indeed being loaded under this recipe?
> > If so, can you present that evidence? (And no, the fact that startup
> > time goes down doesn't mean that loading cus-start is the reason, it
> > could be something else.)
>
>
> Yes, if you add (setq force-load-messages t) to the init file I provided,
> you can see that "Loading cus-start..." is messaged repeatedly, once
> for each time setopt runs. Also, you can see that "Loading cus-start...done"
> never gets messaged, indicating that something failed while loading
> cus-start. I also observe that just calling (require 'cus-start) in that file
> triggers an error.
This is because:
. custom.el and cus-edit.el say (require 'cus-start), something they
don't need to do
. for some reason, 'require' doesn't avoid loading cus-start even if
it is already loaded; the simple patch below reduces the number of
loads of cus-start to just 1 in this scenario
Stefan, why does this happen? It sounds like when 'require' is called
from bytecode, it always loads the file? Or is this something special
for cus-start? Or something else?
Further, that single load of cus-start that is left is also strange:
it comes from cus-load, and stepping with a debugger into Frequire, I
see that cus-start is not in the Vfeatures list? Why?
> > I think this patch changes behavior, so it is not TRT. But before we
> > discuss how to fix the problem, let's be sure we understand the
> > problem and its reason(s).
>
> Sorry, I skipped a few steps in reasoning here. What I am observing from the
> backtrace of the load error mentioned above, is that
> custom-delayed-init-variables
> is set to t when add-to-list runs (on the line following the context
> from the above patch). This is, of course, a type error.
>
> The docstring of custom-delayed-init-variables claims that it is set
> to a non-list
> value when the list has already been processed---so, my reasoning was that
> if it is already set to a non-list value that means there is no point
> adding anything
> to it.
>
> I am happy to consider different ways of solving this issue.
The way to solve this is to understand why 'require' insists on
loading cus-start although it's preloaded. I hope Stefan will help us
understand why this happens.
Here's the patch which reduces the number of loads to 1 (and which I
hoped will reduce it to zero):
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 2ecae54..510c0b9 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -149,7 +149,8 @@ recentf-exclude
(error nil))
(condition-case nil
- (require 'cus-start)
+ (unless (featurep 'cus-start)
+ (require 'cus-start))
(error nil))
(put 'custom-define-hook 'custom-type 'hook)
diff --git a/lisp/custom.el b/lisp/custom.el
index a0dc194..e5ceda8 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -699,7 +699,8 @@ custom-load-symbol
(ignore-errors
(require 'cus-load))
(ignore-errors
- (require 'cus-start))
+ (unless (featurep 'cus-start)
+ (require 'cus-start)))
(dolist (load (get symbol 'custom-loads))
(cond ((symbolp load) (ignore-errors (require load)))
;; This is subsumed by the test below, but it's much faster.
This bug report was last modified 13 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.