Entirely a random sketch because I just want to get this out of my head:
When we went from try!
to ?
it was clear that postfix was a better thing for the way people used Rust.
When we accepted .await
, this truth was reinforced, while also introducing the fascinating precedent of postfix keywords.
I would like to propose, or at least plant the seed of, a massive expansion of the syntax of .await
to anything and everything it would make sense for. We should minimize places where you need to introduce parens to jump between styles.
A particularly egregious case I am frequently cursed with is casts and ref/deref.
&mut *((&mut x.y as *mut T as *mut U).add(idx) as *mut V);
With the new cast methods on ptr we now have:
&mut *(&mut x.y as *mut T).cast::<U>().add(idx).cast::<V>();
which is certainly better but what if we could write (strawman):
x.y.&mut // <-- we have the ref and mut keywords if you prefer
.as::<*mut T> // <-- no parens, debatable
.cast::<U>()
.add(idx)
.cast::<V>()
.*.&mut; // <-- sadly no reserved deref keyword, and it's
// used in the Deref trait so not great for editions
(note ref raw
might also be fine to introduce as a concept here as well)
Minor notes from the little I have thought about this:
.& is potentially ambiguous thanks to the nightmare of 0.
being a valid float literal. 0.&1.
/ 0.&x
is an interesting expression to consider. Is it taking a reference to the the float literal "0."? Might we misparse this as a fragment of a field access? As a human I can correctly determine "no" because the expression starts with a number (indicating a literal and not an ident), and the & is followed by another sub-expression, instead .
to continue the chain or some sort of expression terminator like ;
or )
.
But I can't remember enough about parsers to know if these arguments work out formally in an LRKG(7) or whatever system we prefer our grammars to conform to.
Anyway: we should take the precedent of .await
seriously, as a thing to use more!