Subject: bug#23648: [PATCH] `defun-declarations-alist' can be unintentionally modified

From: [email-masked]
Date: Wed, 20 Jul 2016 21:09:42 -0400

Eli Zaretskii <[email-masked]> writes:

>> From: Michael Heerdegen <[email-masked]>
>> Cc: Noam Postavsky <[email-masked]>,  [email-masked],  [email-masked]
>> Date: Mon, 18 Jul 2016 23:28:55 +0200
>> 
>> Eli Zaretskii <[email-masked]> writes:
>> 
>> > Sorry, I guess I'm too stupid to understand this advanced stuff.  Or
>> > maybe it's too late.
>> 
>> I think the example uses macroexpand only to demonstrate what (obviously
>> ill) code you will get when you compile the mentioned form after
>> performing the completion as mentioned.
>
> Thanks, but I'm still none the wiser about the questions I asked.

Hmm, maybe it will be clearer like this:

Evaluate:

(macroexpand '(defun foo ()
                (declare (indent 1))
                nil)) ;=> (prog1 (defalias (quote foo) (function (lambda nil nil))) (function-put (quote foo) (quote lisp-indent-function) (quote 1)))

This gives the correct result (the (function-put...) part comes from the
(declare (indent 1))).

Now perform a completion on a declare clause, e.g., put cursor after
"ind" and hit C-M-i: (declare (ind)) completes to (declare (indent)).

Now evaluate the same expression as before:

(macroexpand '(defun foo ()
                (declare (indent 1))
                nil)) ;=> (prog1 (defalias (quote foo) (function (lambda nil nil))) "Warning: Unknown defun property ‘indent’ in foo")

This give the wrong result, the (declare (indent 1)) is giving the
"Warning:...".  Emacs has unlearned the indent declaration.  In fact it
unlearned all the declarations for defun except for gv-setter, you can
see this by looking at defun-declarations-alist's value.