If only it were that simple:
// E.g. 'fn() as Int << 2'.
// In this case '<<' has higher precedence than 'as', but the LHS should
// be 'fn() as Int' instead of 'Int'.
// If the left-hand-side is a 'try' or 'await', hoist it up turning
// "(try x) + y" into try (x + y).
// If this is an assignment operator, and the left operand is an optional
// evaluation, pull the operator into the chain.
// If the right operand is a try or await, it's an error unless the operator
// is an assignment or conditional operator and there's nothing to
// the right that didn't parse as part of the right operand.
//
// Generally, nothing to the right will fail to parse as part of the
// right operand because there are no standard operators that have
// lower precedence than assignment operators or the conditional
// operator.
//
// We allow the right operand of the conditional operator to begin
// with 'try' for consistency with the middle operand. This allows:
// x ? try foo() : try bar()
// but not:
// x ? try foo() : try bar() $#! 1
// assuming $#! is some crazy operator with lower precedence
// than the conditional operator.
// If the operator is a cast operator, the RHS can't extend past the type
// that's part of the cast production.