Files
rust/compiler
bors 3ea2fbcb2a Auto merge of #154010 - estebank:issue-42753, r=nnethercote
Suggest using equality comparison instead of pattern matching on non-structural constant in pattern

When encountering a pattern containing a non-structural constant (not marked as `#[derive(PartialEq)]` to make it suitable for pattern matching, `C` in the examples below), we would previously not provide additional guidance. With this PR, the `help` in the following examples are added:

```
error: constant of non-structural type `partial_eq::S` in a pattern
  --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:16:18
   |
LL |     struct S;
   |     -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL |     const C: S = S;
   |     ---------- constant defined here
...
LL |             Some(C) => {}
   |                  ^ constant of non-structural type
   |
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
  --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5
   |
LL |     impl PartialEq<S> for S {
   |     ^^^^^^^^^^^^^^^^^^^^^^^
help: add a condition to the match arm checking for equality
   |
LL -             Some(C) => {}
LL +             Some(binding) if binding == C => {}
   |
```

```
error: constant of non-structural type `partial_eq::S` in a pattern
  --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:22:18
   |
LL |     struct S;
   |     -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL |     const C: S = S;
   |     ---------- constant defined here
...
LL |         let Some(C) = Some(S) else { return; };
   |                  ^ constant of non-structural type
   |
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
  --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5
   |
LL |     impl PartialEq<S> for S {
   |     ^^^^^^^^^^^^^^^^^^^^^^^
help: check for equality instead of pattern matching
   |
LL -         let Some(C) = Some(S) else { return; };
LL +         if Some(C) == Some(S) { return; };
   |
```

The suggestion accounts for a few conditions:

 - if the type is not from the local crate and has no `PartialEq` impl, the user can't make it structural, so we don't provide the suggestion
 - regardless of whether the type is local or remote, if it has a manual `PartialEq`, explain that with a derived `PartialEq` you could use equality
 - if the type is local and has no impl, suggest adding a derived `PartialEq` and use equality check instead of pattern matching
 - when suggesting equality, account for `if-let` to suggest chaining (edition dependent), `match` arm with a present `if` check, `match` arm without an existing `if` check
 - when encountering `let-else`, we suggest turning it into an `if` expression instead (this doesn't check for additional bindings beyond the constant, which would suggest incorrect code in some more complex cases).

Fix rust-lang/rust#42753.
2026-03-26 05:30:08 +00:00
..
2026-03-11 06:25:23 +11:00
2026-03-12 14:37:51 +01:00