You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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#42753.
#[label("`{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns")]
1056
+
#[label(
1057
+
"{$is_local ->
1058
+
*[true] `{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
1059
+
[false] `{$ty}` is not usable in patterns
1060
+
}"
1061
+
)]
1057
1062
pub(crate)ty_def_span:Span,
1058
1063
pub(crate)ty:Ty<'tcx>,
1059
1064
#[note(
1060
-
"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"
1065
+
"the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see \
1066
+
https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details"
0 commit comments