Subject: bug#45428: 27.1; (quote (quote (quote ...))) unexpectedly works as anonymous face

From: Drew Adams <[email-masked]>
Date: Tue, 29 Dec 2020 10:27:11 -0800 (PST)

> The original bug report said something different:...
> However, that original complaint is incorrectly assuming that a face
> can _only_ have the form of an anonymous face, which is a property
> list of attribute/value pairs.  The text it quotes from section 39.12
> of the ELisp manual is incomplete; here it is in its entirety:
> 
>   One way to represent a face is as a property list of attributes, like
>   ‘(:foreground "red" :weight bold)’.  Such a list is called an "anonymous
>   face".  For example, you can assign an anonymous face as the value of
>   the ‘face’ text property, and Emacs will display the underlying text
>   with the specified attributes.  *Note Special Properties::.

I think it would help if that simple "See Special Properties"
were called out explicitly as telling you to see that
node for a complete description of the `face' property.
The text before it and after it can indeed give a false
impression about property `face' and how a face can be
represented. 

> If you follow the cross-reference to "Special Properties", you will
> find that the value of the 'face' property can be one of the
> following:
> 
>   . a face symbol
>   . a property list of attribute/value pairs
>   . a cons cell of the form (foreground-color . COLOR)
>   . a cons cell of the form (background-color . COLOR)
>   . a list of faces, each one given by any of the above forms
>   . a cons cell of the form (:filtered FILTER FACE-SPEC), where
>     FACE-SPEC is one of the above forms
> 
> And now you should recognize that the strange format of the property
> value, which prompted the original bug report, fits the "list of
> faces" format as described by the 5th item in the above list.

Indeed.  I thought that's what you might say.  Yes,
that description is fine.  But I hope you'll recognize
that the (quote (quote '(...))) example is a gotcha,
especially given that the "Invalid face reference:
quote" message is shown in *Messages* only after some
action provokes redisplay, and it often is not seen
in the echo area.  Without your having piped up here
to say "Please look in *Messages*" I wouldn't have
noticed it, for example.

If this were a court of law, your argument that the
doc is fine would be convincing.  But if we're trying
to help and guide users, then I think this `quote'
gotcha could be handled better.

Better still perhaps, instead of trying to address
the specific `quote' gotcha (which is particularly
misleading), the "Invalid face..." interaction could
perhaps be improved.  If that msg were (1) more
visible and immediate and (2) said more about what
is invalid (even just pointing out that here `quote'
is taken as a face name or whatever), that might help.

> So I still don't see a problem with the documentation in this case.

See above.  We could maybe help users a bit more,
without giving up any of the exactness of the spec
given in `Special Properties' etc.

> I think the only problem/surprise here could be that Emacs acted
> according to a single valid part of the face spec and seemingly
> silently ignored the invalid ones, logging an error message in
> *Messages* instead of perhaps rejecting it wholesale, and the OP
> failed to look in *Messages*.  

Yes, now we're thinking along the same lines.  The
real problem is the interaction with the user and
the inadequacy of the message, IMO.

> However, that doesn't seem to be a bug:
> the face spec is invalid, 

Yes, but can we say why, in what way, what about
it is invalid?

(If the doc in question actually referred to
"face spec" instead of "face" or "face
representation", that would be a start.  It would
guide user toward the part of the doc that says
what can be in a face spec.)

> and so invokes undefined behavior, where we
> only have an obligation not to crash nor lock up Emacs (which is why
> the error message isn't displayed as such: the face merging happens at
> display time, and we cannot usefully signal an error from redisplay).

I was afraid you might say that.  All I can say
is that if we can possibly do something better
that would help.  There are gotchas in Emacs
that we can't really prevent or guide users away
from (e.g. using existing names of things in
perverted, misleading ways).  I was hoping this
is one where we might be able to help a bit.

> > Having heard the misunderstanding that we've made
> > (still without my understanding, so far), do you
> > have a suggestion for how to dispel/prevent it?
> 
> Tell users to read the docs?  But we already know
> that doesn't really work...

In this case, the problem (IMO) is that the doc
they are led to doesn't guide them to the doc that
really helps with this.  See above.