Skip to content

Add partialeq_to_none lint #9288

New issue

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

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

Already on GitHub? # to your account

Merged
merged 1 commit into from
Aug 9, 2022
Merged

Conversation

lukaslueg
Copy link
Contributor

Initial implementation of #9275, adding lint partialeq_to_none. This is my first time working on clippy, so please review carefully.

I'm unsure especially about the Sugg, as it covers the entire BinOp, instead of just covering one of the sides and the operator (see the multi-line example). I was unsure if pinpointing the suggestion wouldn't be brittle...

changelog: [PARTIALEQ_TO_NONE]: Initial commit

@rust-highfive
Copy link

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Jarcho (or someone else) soon.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 3, 2022
@Jarcho
Copy link
Contributor

Jarcho commented Aug 5, 2022

Implementation looks fine. Two things before merging:

  • Should this be a style lint or a pedantic lint. I'm leaning towards style.
  • I don't particularly like PartialEq in the lint name. There's nothing really wrong with it and it's not misleading, but it seems like unnecessary detail. eq_none might be better.

@lukaslueg
Copy link
Contributor Author

lukaslueg commented Aug 5, 2022

          // We are only interested in comparisons between `Option` and a literal `Option::None`
          let scrutinee = match (
              is_none_ctor(left_side) && is_ty_option(right_side),
              is_none_ctor(right_side) && is_ty_option(right_side),
          ) {
              (true, false) => right_side,
              (false, true) => left_side,
              _ => return,
          };

Do we even need the is_ty_option() (don't mind the right_side bug 👀😅) to rule out comparisons like 1u32 == None? AFAICS, as a LateLintPass comes after type-resolution, non-applicable comparisons are already ruled out?!

@lukaslueg
Copy link
Contributor Author

Also: x != &None does not trigger because the Expr &None is not is_lang_ctor(.., .., LangItem::OptionNone). How to peel off the references from a QPath akin to Ty::peel_refs?

@Jarcho
Copy link
Contributor

Jarcho commented Aug 5, 2022

You do need to check for an option type as PartialEq can be implemented across types.

You can use clippy_utils::peel_hir_expr_refs.

@lukaslueg
Copy link
Contributor Author

lukaslueg commented Aug 6, 2022

Moving from nursery to style enables the lint by default, which causes it to get triggered in other ui-tests. For instance:

&& a.len() == 3
&& c != None
&& !a.is_empty()

Should I update the triggering code in the ui-tests, bless the results, or allow(clippy::partialeq_to_none) in those ui-tests?

I don't feel strongly about the name, yet I think partialeq is more precise because the lint covers both eq and ne from the PartialEq trait (while recognizing that up to now we don't cover fully qualified syntax).

lintcheck has one extra warning wrt to

https://github.com/rust-lang/cargo/blob/0ced33b1656b0dbe3dece629a77768db74ed5bd7/src/cargo/ops/cargo_new.rs#L500

which is correct.

@Jarcho
Copy link
Contributor

Jarcho commented Aug 7, 2022

Normally adding allow in tests is the better approach. It's possible the change can cause the test to no longer function.

For the lint name, use whichever one you prefer.

@lukaslueg
Copy link
Contributor Author

I've had to make some changes to get the suggestions right (see the Box-example). LGTM

@Jarcho
Copy link
Contributor

Jarcho commented Aug 8, 2022

Looks good. You can squash the changes.

@lukaslueg
Copy link
Contributor Author

Squashed

@Jarcho
Copy link
Contributor

Jarcho commented Aug 9, 2022

Thank you. @bors r+

@bors
Copy link
Contributor

bors commented Aug 9, 2022

📌 Commit 657b0da has been approved by Jarcho

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Aug 9, 2022

⌛ Testing commit 657b0da with merge 3af9072...

@bors
Copy link
Contributor

bors commented Aug 9, 2022

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Jarcho
Pushing 3af9072 to master...

@trevyn
Copy link

trevyn commented Aug 28, 2022

I'm hitting this lint for code of the form foo == option_env!("BAR"), is that intended?

@llogiq
Copy link
Contributor

llogiq commented Aug 28, 2022

Perhaps we should add a macro check for the None expr.

@lukaslueg
Copy link
Contributor Author

@trevyn Thanks for the comment. The lint is certainly wrong as it would hardcode whatever option_env expanded to at that time.

bors added a commit that referenced this pull request Aug 28, 2022
Don't lint literal `None` from expansion

This addresses #9288 (comment): If the literal `None` is from expansion, we never lint. This is correct because e.g. replacing the call to `option_env!` with whatever that macro expanded to at the time of linting is certainly wrong.

changelog: Don't lint [`partialeq_to_none`] for macro-expansions
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants