Subject: bug#74349: 30.0.92; Visiting a file under c-ts-mode loads cc-mode

From: Eli Zaretskii <[email-masked]>
Date: Thu, 14 Nov 2024 08:35:26 +0200

> From: Stefan Monnier <[email-masked]>
> Cc: [email-masked]
> Date: Wed, 13 Nov 2024 15:42:21 -0500
> 
> > So the C file was correctly visited using c-ts-mode, but cc-mode was
> > still loaded, quite unexpectedly.
> 
> Could you clarify why you think it's a problem?

cc-mode is large; loading it brings in many other cc-* files, which
basically in this scenario are just ballast.  In the
native-compilation case, this means loading quite a few additional
*.eln files which are not really used.  It's not "economical", and
looks unclean to me.

There's also the issue of the adverse consequences of loading cc-mode
discussed in bug#74339.  I hope those will be solved soon, but their
current existence was the motivation for me to examine each and every
reason for loading cc-mode when I didn't expect that to happen.

> > Moreover, the settings in our .dir-locals.el that are defined for
> > c-mode were applied to the buffer which is not under c-mode.
> 
> Could you similarly clarify why you think it's a problem?

It was unexpected, that's all.

> >   . hack-dir-local-variables 'funcall's the mode symbol when
> >     processing directory-local variables for that mode
> 
> It doesn't "funcall" it, but it does make sure the function is loaded:
> 
>               ;; If KEY is an extra parent it may remain not loaded
>               ;; (hence with some of its mode-specific vars missing their
>               ;; `safe-local-variable' property), leading to spurious
>               ;; prompts about unsafe vars (bug#68246).
>               (if (and (symbolp key) (autoloadp (indirect-function key)))
>                   (ignore-errors (autoload-do-load (indirect-function key))))
> 
> > I didn't expect derived-mode-add-parents to cause c-mode be turned on,
> 
> It's not turned on: its file loaded.

Why does it need to be loaded in this case?  Is there some technical
reason to do so in order to perform the settings of the variables
defined by that mode?  Or is this just an artifact of the
implementation of hack-dir-local-variables, and thus could be avoided?

> > and its directory-local settings be applied, when c-ts-mode is
> > used to visit a file.
> 
> Looks like you forgot about it, but yes, that was discussed explicitly
> when we discussed `derived-mode-add-parents`.  We decided back then that
> the extra var-settings will likely be harmless.

I guess I did forget.  But the main issue for me here is that cc-mode
is loaded, not that the variables are defined.

> > Can this be avoided, please?  Users who want to use c-ts-mode for C
> > files will not necessarily be happy to have cc-mode and all its
> > dependencies loaded, and the c-mode-related settings applied, just
> > because of unrelated c-mode settings in .dir-locals.el.  It bloats the
> > memory footprint of Emacs for no good reason,
> 
> Maybe we could try and add more tests in the above code before deciding
> to `autoload-do-load`.  E.g. we could first check the list of variables
> being set and if they all already have a `safe-local-variable` property,
> then we don't need to autoload the mode (and then we'd have to make sure
> CC-mode's `safe-local-variable` settings are all autoloaded).

If that could be done, I think it would be a good thing, yes.

> > and it modifies variables the user didn't mean to touch.
> 
> We don't really know that without reading the user's mind, in the
> general case.  Maybe the `c-mode` settings set only things like
> `indent-tabs-mode` and `require-final-newline` and the users definitely
> want them to apply to any mode used for the C files rather than only for
> the `cc-c-mode`.

Right, I see the logic of setting the variables now.