Add new matches_instead_of_eq lint - #17018
Conversation
d8ab39c to
97608f8
Compare
|
Lintcheck changes for 528c1a0
This comment will be updated if you push new changes |
97608f8 to
36f7572
Compare
|
With dogfood errors, I was able to strenghten quite a lot the lint and handle suggestions with dereferencing. One of the nice changes that came with this lint is: - if cx
- .tcx
- .crate_types()
- .iter()
- .any(|t: &CrateType| matches!(t, CrateType::ProcMacro))
- {
+ if cx.tcx.crate_types().contains(&CrateType::ProcMacro) { |
|
Maybe a nit: If the type being compared is |
|
Very good point. I'll handle this case as well, thanks! |
b7af90a to
b5f52cd
Compare
|
Added suggested change. |
|
|
||
| declare_clippy_lint! { | ||
| /// ### What it does | ||
| /// Checks for the use of `matches!` with types that implement `PartialEq` (not manually). |
There was a problem hiding this comment.
| /// Checks for the use of `matches!` with types that implement `PartialEq` (not manually). | |
| /// Checks for the use of `matches!` with types that automatically derive `PartialEq`. |
| } | ||
|
|
||
| cx.tcx.for_each_relevant_impl(partial_eq_def_id, expr_ty, |impl_id| { | ||
| if !cx.tcx.is_automatically_derived(impl_id) { |
There was a problem hiding this comment.
I think this won't catch types whose components have a non-automatically-derived PartialEq, for example here:
enum E { … }
impl PartialEq for E {
…
}
#[derive(PartialEq)]
struct S(E);
fn f(s: &S) {
if matches!(s, S(E::…)) { … }
}In this case, we have multiple choices:
- not lint
- lint with
MaybeIncorrectand a note saying thatE'sPartialEqmay not behave as pattern matching
While in other cases, I think we can lint with MachineApplicable.
There was a problem hiding this comment.
I think we shouldn't lint in this case to follow the "do not lint if manual PartialEq impl" rule.
|
The check will have to be carefully placed as to not analyze all types
recursively every time there is a `matches!` macro call. You might also
want to cache the analysis results.
|
This comment has been minimized.
This comment has been minimized.
b5f52cd to
24d0b01
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
Finally took the time to implement the suggestion for transitive non-automatic |
|
This lint is highly reliant on the optimizer and the optimizer is highly unreliable. The more complex the body containing the match is, the more likely the optimizer is to fail. See https://godbolt.org/z/9zosK9WMj for a simple example. For a pattern like |
|
@Jarcho: Just to confirm: did you comment on the right PR? This is a pedantic lint, not a perf one. Or did I misunderstand your point? |
24d0b01 to
528c1a0
Compare
|
Fixed dogfood. :) |
|
The lint is suggesting something with notable performance regression. The category of the lint isn't relevant. |
|
Interesting: it doesn't inline the |
|
Just thought: seems like a bug in rustc/LLM rather than coming from this lint. So from here, should we wait for a solution upstream or is it ok to move forward with this lint? |
|
This isn't really a bug. {
let tmp = Some(0);
PartialEq::eq(&value, &tmp)
}
discriminant(&value) == CONSTANT
&& read_enum_field!(value, CONSTANT, 0) == 0There compiler can't assume that |
|
I thought the |
|
It's a normal function with normal inlining rules (The derive adds |
|
☔ The latest upstream changes (possibly #17369) made this pull request unmergeable. Please resolve the merge conflicts. |
|
There is an unstable marker trait, |
View all comments
Fixes #14688.
r? @samueltardieu
changelog: Add new pedantic
matches_instead_of_eqlint