1
Fork 0

Tighten up assignment operator representations.

In the AST, currently we use `BinOpKind` within `ExprKind::AssignOp` and
`AssocOp::AssignOp`, even though this allows some nonsensical
combinations. E.g. there is no `&&=` operator. Likewise for HIR and
THIR.

This commit introduces `AssignOpKind` which only includes the ten
assignable operators, and uses it in `ExprKind::AssignOp` and
`AssocOp::AssignOp`. (And does similar things for `hir::ExprKind` and
`thir::ExprKind`.) This avoids the possibility of nonsensical
combinations, as seen by the removal of the `bug!` case in
`lang_item_for_binop`.

The commit is mostly plumbing, including:
- Adds an `impl From<AssignOpKind> for BinOpKind` (AST) and `impl
  From<AssignOp> for BinOp` (MIR/THIR).
- `BinOpCategory` can now be created from both `BinOpKind` and
  `AssignOpKind`.
- Replaces the `IsAssign` type with `Op`, which has more information and
  a few methods.
- `suggest_swapping_lhs_and_rhs`: moves the condition to the call site,
  it's easier that way.
- `check_expr_inner`: had to factor out some code into a separate
  method.

I'm on the fence about whether avoiding the nonsensical combinations is
worth the extra code.
This commit is contained in:
Nicholas Nethercote 2024-12-20 10:15:05 +11:00
parent ac8ccf09b4
commit ddcb370bc6
26 changed files with 391 additions and 239 deletions

View file

@ -1572,8 +1572,7 @@ impl<'a> State<'a> {
hir::ExprKind::AssignOp(op, lhs, rhs) => {
self.print_expr_cond_paren(lhs, lhs.precedence() <= ExprPrecedence::Assign);
self.space();
self.word(op.node.as_str());
self.word_space("=");
self.word_space(op.node.as_str());
self.print_expr_cond_paren(rhs, rhs.precedence() < ExprPrecedence::Assign);
}
hir::ExprKind::Field(expr, ident) => {