Subject: Re: bug#69467: 29.2; user-init-file set to .../lisp/progmodes/compile.el.gz

From: Eli Zaretskii <[email-masked]>
Date: Thu, 29 Feb 2024 15:08:40 +0200

> Cc: Jonas Bernoulli <[email-masked]>
> Date: Fri, 01 Mar 2024 01:23:50 +1300
> From: Phil Sainty <[email-masked]>
> 
> I recently encountered this undesirable side-effect when using the
> https://github.com/emacscollective/auto-compile library in conjunction
> with a byte-compiled init file.  The combination is reliably resulting
> in `user-init-file' being set to the .../lisp/progmodes/compile.el.gz
> path, with ensuing chaos (e.g. customized settings being written to
> that file -- I first became aware of this problem while using emacs -Q
> when it suddenly acquired some custom faces from my regular config as
> something loaded the compile library!).
> 
> The purpose of the auto-compile package is to ensure that .elc files
> are always up-to-date and loaded in preference to .el files.  I've been
> using it for many years and wasn't aware of having had any issues with
> it in the past, but I do not typically have a byte-compiled init.elc
> file.  The auto-compile code advises `load' and `require' (which does
> seem like it could present risks), however it seems so very odd to me
> that user-init-file could end up with this value for any reason that
> it seems like it might ultimately be an Emacs bug.
> 
> I raised it with the auto-compile maintainer (Jonas Bernoulli, CC'd)
> at https://github.com/emacscollective/auto-compile/issues/33 and we
> couldn't make sense of it at the time, so I'm escalating it here.
> 
> The attached bash shell recipe reproduces the issue in Emacs 29.
> I can reproduce it in all of Emacs 27, 28, 29, 30 (and not 26.3 or
> 25.3), but this recipe uses the --init-directory option which was
> added in 29.1.
> 
> (See attached script.)
> 
> The echo area in the final instance of Emacs should report the path to
> compile.el.gz (and re-running the final "touch init.el && ..." command
> will repeat that result each time).
> 
> 
> If I put (debug) at the top of compile.el.gz then I get the following
> backtrace, so we can see how/why compile.el is getting involved, but
> it just seems very wrong for that path to be able to end up being the
> user-init-file value.
> 
> 
> Debugger entered: nil
>    byte-code(...)
>    compilation-mode()
>    emacs-lisp-compilation-mode()
>    byte-compile-log-file()
>    byte-compile-from-buffer(#<buffer  *Compiler Input*>)
>    byte-compile-file("/tmp/autocomp/init.el")
>    auto-compile--byte-compile-file("/tmp/autocomp/init.el")
>    auto-compile-on-load("/tmp/autocomp/init" nil)
>    load@auto-compile("/tmp/autocomp/init" noerror nomessage)
>    apply(load@auto-compile ("/tmp/autocomp/init" noerror nomessage))
>    load("/tmp/autocomp/init" noerror nomessage)
>    startup--load-user-init-file(#f(compiled-function () #<bytecode 
> -0x54c765b3b165b77>) #f(compiled-function () #<bytecode 
> -0xe2e004ca56aeafc>) t)
>    command-line()
>    normal-top-level()

Are you sure load@auto-compile adheres to the protocol that is
described in the doc string of startup--load-user-init-file?  That is,
that this function is expected to set user-init-file to the name of
the init-file it loads?  IOW, step through or trace the code in
startup--load-user-init-file and see what happens there with the value
of user-init-file, and note that filename-function and
alternate-filename-function are expected to return the name of the
file they load.

> As it seems to have started in Emacs 27, my *guess* is that it's
> connected to the early-init.el system which was added in Emacs 27,
> but I've not dug any further at this stage.

Maybe it's related to early-init-file, or maybe it's related to a
thorough rewrite of startup--load-user-init-file which was needed to
support the early-init-file.