fn write_dot_receiver<W: Write, T: AstInfo>(
f: &mut AstFormatter<W>,
expr: &Expr<T>,
)Expand description
Write expr as the receiver of a . operator (used by FieldAccess and
WildcardAccess), parenthesizing when the receiver could re-bind the
trailing dot on reparse. The . token has very high precedence and both
the lexer and parser greedily extend adjacent tokens: 1.x tokenizes the
number 1. and leaves x as an alias, and 'a'::T.x consumes T.x as a
qualified type name. The whitelist below covers receivers that print as
self-terminating syntax (parenthesized exprs, function calls, bracketed
collections, etc.). Anything else gets explicit parens.
A bare Identifier/QualifiedWildcard receiver is not safe: a then
.b/.* prints as a.b/a.*, which reparses as the qualified identifier
Identifier([a, b]) / QualifiedWildcard([a]) rather than a field/wildcard
access. The parser only ever builds those accesses over a parenthesized
receiver ((a).b), so it wraps the name in Expr::Nested. A bare name here
is a Nested-stripped AST and must be re-parenthesized. A FieldAccess /
WildcardAccess receiver is safe, because its own printing already
parenthesizes a bare-name base ((a).b.c), so the chain stays self-delimiting.
The quantified-subquery forms (AnySubquery/AllSubquery, printed
<expr> <op> ANY (<query>)) are likewise not safe: they end in a (query)
that is only a sub-part, so a trailing .x/.* binds to that inner subquery
rather than the whole expression. (Contrast Subquery/ArraySubquery/… which
are a single (…)/ARRAY(…) primary, so a trailing dot attaches to the whole
thing.)