Subject: bug#7767: 23.2.91; file-local-variables-alist should have the permanent-local property

From: Stefan Monnier <[email-masked]>
Date: Sat, 01 Jan 2011 22:58:45 -0500

close 7767
thanks

>>> I tried to debug the problem and it seems that `hack-local-variables'
>>> will collect the local variables into `file-local-variables-alist' than
>>> run the hook `before-hack-local-variables-hook' which containts the
>>> function `c-before-hack-hook'.
>>> `c-before-hack-hook' will see the `mode' variable and call `c++-mode'
>>> which than will call `kill-all-local-variables' setting
>>> `file-local-variables-alist' to nil so that the remaining variables are
>>> not processed.
>> 
>> It sounds like cc-mode does something odd here.

> On further investigation, this only happens when the mode setting 
> changes the mode of the file.  That is, a file named "hello.c" with a 
> "mode: c++" setting.  It does not happen otherwise, because 
> `hack-one-local-variable' will not enable a major mode if it is 
> already set for the file.

> However, `c-before-hack-hook' does enable the mode itself via a call to 
> `hack-one-local-variable'.

On further investigation, I see that in modes other than cc-mode,
a similar problem appears: the mode is set properly and the local
variables are set correctly, but file-local-variables-alist ends up nil
in the buffer (including when hack-local-variables-hook is run), which
is not right.

More specifically, it's the same bug that manifests itself differently
because in the non-cc case, the file-local-variables-alist gets set to
nil a bit later, more specifically it's set right after reading
file-local-variables-alist to set up the loop that calls
hack-one-local-variable.

So, I agree with your original analysis and have installed the change
below to the emacs-23 branch.  Thank you,

        Stefan

=== modified file 'lisp/files.el'
--- lisp/files.el	2010-12-04 21:45:17 +0000
+++ lisp/files.el	2011-01-02 03:47:28 +0000
@@ -2788,6 +2788,7 @@
 specified.  The actual value in the buffer may differ from VALUE,
 if it is changed by the major or minor modes, or by the user.")
 (make-variable-buffer-local 'file-local-variables-alist)
+(put 'file-local-variables-alist 'permanent-local t)
 
 (defvar dir-local-variables-alist nil
   "Alist of directory-local variable settings in the current buffer.