#180 rst.el: self-modifying code

closed-fixed
Stefan Merten
emacs mode (11)
6
2012-04-30
2012-01-25
Jakub Wilk
No

I'm forwarding a bug reported by Samuel Bronson, originally at <http://bugs.debian.org/657269>:

This is the expression for the default value of the customization setting `rst-adornment-faces-alist':

,----
| (let ((alist '((t . font-lock-keyword-face)
| (nil . font-lock-keyword-face)))
| (i 1))
| (while (<= i rst-level-face-max)
| (nconc alist (list (cons i (intern (format "rst-level-%d-face" i)))))
| (setq i (1+ i)))
| alist)
`----

According to the elisp manual (which refers to this as "STANDARD"):

,----[ (elisp) Variable Definitions ]
| The expression STANDARD can be evaluated at various other times,
| too--whenever the customization facility needs to know OPTION's
| standard value. So be sure to use an expression which is harmless
| to evaluate at any time. We recommend avoiding backquotes in
| STANDARD, because they are not expanded when editing the value, so
| list values will appear to have the wrong structure.
`----

Unfortunately, the expression above is not safe to evaluate more than once, because it has the side effect of modifying the very data structure representing the expression. This happens because of the way it passes the value of a list literal to `nconc', which destructively modifies its arguments.

You can see the problem by customizing the variable `rst-level-face-max' to a few different values, then asking customize to show the saved lisp expression for `rst-adornment-faces-alist' (without having customized that).

A quick fix would be to use a copy of the literal list, as in the patch below.

Discussion

  • Stefan Merten
    Stefan Merten
    2012-01-25

    • priority: 5 --> 6
    • assigned_to: nobody --> smerten
     
  • Stefan Merten
    Stefan Merten
    2012-04-30

    Contained in the next release of rst.el. Thanks to Samuel Bronson for the patch.

     
  • Stefan Merten
    Stefan Merten
    2012-04-30

    • status: open --> closed-fixed