Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tighten up assignment operator representations. #138017

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

nnethercote
Copy link
Contributor

This is step 3 of MCP 831.

r? @spastorino

First, move the `lang_item_for_op` call from the top of
`lookup_op_method`'s body to its callsites. It makes those callsites a
little more verbose, but also means `lookup_op_method` no longer cares
whether it's handling a binop or unop. This lets us remove `Op` and
split `lang_item_for_op` into `lang_item_for_{bin,un}op`, which is a
little simpler.

This change is a prerequisite for adding the `ast::AssignOpKind` type in
a subsequent commit.
Because it's nice to avoid passing in unnecessary data.
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.
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 4, 2025
@rustbot
Copy link
Collaborator

rustbot commented Mar 4, 2025

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @davidtwco, @vakaras

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@nnethercote
Copy link
Contributor Author

@spastorino: I'm not 100% certain we should do this. It does make the representation better in the sense that it makes it impossible to express some nonsensical combinations, such as ExprKind::AssignOp(BinOpKind::Lt) (there is no &&= operator). But it makes the code longer, and we have to do some extra type conversions in a few places.

I suggest starting with the third commit, which is the most important one. If you are happy with how it looks, then look at the first and second commits, which are just some preliminary refactorings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants