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

Added new non_zero_suggestions lint #13167

Merged
merged 8 commits into from
Sep 7, 2024
Merged

Conversation

Samarth1696
Copy link
Contributor

@Samarth1696 Samarth1696 commented Jul 26, 2024

Created lint based on the suggestions in #7291

  • Followed [lint naming conventions][lint_naming]
  • Added passing UI tests (including committed .stderr file)
  • cargo test passes locally
  • Executed cargo dev update_lints
  • Added lint documentation
  • Run cargo dev fmt

changelog: new [non_zero_suggestions] lint

@rustbot
Copy link
Collaborator

rustbot commented Jul 26, 2024

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @dswij (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jul 26, 2024
Copy link
Member

@J-ZhengLi J-ZhengLi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 welcome~

I'm just stopping by and left some comments.

(btw, I didn't go through the details, only pointing out something rather obvious~)

clippy_lints/src/non_zero_suggestions.rs Outdated Show resolved Hide resolved
tests/ui/non_zero_suggestions.rs Outdated Show resolved Hide resolved
Comment on lines 50 to 52
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if let ExprKind::Call(func, [arg]) = expr.kind {
if let ExprKind::Path(qpath) = &func.kind {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe check if the expr is a binary expression first? Therefore the below example doesn't cause error after applying lint suggestion:

let x: u64 = u64::from(NonZeroU32::new(5).unwrap());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First I thought like that only, based on the suggestion from the issue but then I thought do we need it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to check for binary expr?

Copy link
Member

@J-ZhengLi J-ZhengLi Jul 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think yes? Notice that the tests are failing because the lint shouldn't suggestion a fix to a non-binary expr:

error[E0308]: mismatched types
  --> tests/ui/non_zero_suggestions.fixed:68:5
   |
LL | fn no_bin_exp(x: u64, y: NonZeroU32) -> u64 {
   |                                         --- expected `u64` because of return type
LL |     NonZeroU64::from(y)
   |     ^^^^^^^^^^^^^^^^^^^ expected `u64`, found `NonZero<u64>`
   |
   = note: expected type `u64`
            found struct `std::num::NonZero<u64>`
help: call `Into::into` on this expression to convert `std::num::NonZero<u64>` into `u64`
   |
LL |     NonZeroU64::from(y).into()
   |                        +++++++

In this case, you shouldn't give a MachineApplicable suggestion at least, as it's telling rustfix to apply that suggestion because it's "always correct", but that's not the case since there could be type difference. I think the original issue specifically limit the cases to binary expr was because that they wanted to play safe, as the resulting type of an integer that add|sub|div|mul|... another NonZero type is still the integer type itself (example), so it can always being replaced to the NonZero type directly.

I think you could try adjusting the applicability base on whether the expr is binary or not, if yes, you can continue to offer a MachineApplicable suggestion as it is. But if not, you should state the applicability as MaybeIncorrect, so when a user runs clippy with --fix, it wouldn't cause any suggestion-cause-error issue.
For example, you could try something like this:

let mut appllicability = Applicability::MaybeIncorrect;
if let ExprKind::Binary(_, _, rhs) = expr.kind {
    applicability = Applicability::MachineApplicable;
    check_for_fn(...);
} else {
    check_for_fn(...);
}

If you decided to do this, you may split the test cases to non-fixable and fixable tests, because in clippy, the suggestion will always get applied no matter the applicability. (There are some lints that does this, search files that end with fixable for hints)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you are right. Limiting the lint to binary expressions would be better. It avoids complex cases and aligns with the original intent of the issue. I'll focus on implementing this change and add relevant test cases. I'll update the PR soon with these changes.

@Samarth1696
Copy link
Contributor Author

Samarth1696 commented Jul 29, 2024

Thank you very much for your thorough review and helpful suggestions, @J-ZhengLi ^^. Actually this is my first PR towards Open Source. 😅

@J-ZhengLi
Copy link
Member

Thank you very much for your thorough review and helpful suggestions, @J-ZhengLi ^^. Actually this is my first PR towards Open Source. 😅

❤️ Already doing pretty good then, keep it up~

@Samarth1696
Copy link
Contributor Author

All fixed! can you check? @J-ZhengLi

@J-ZhengLi
Copy link
Member

r? clippy

could someone have the time to take a look at this?

@rustbot rustbot assigned llogiq and unassigned dswij Aug 30, 2024
Copy link
Contributor

@llogiq llogiq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already looks good, I merely have a suggestion for an optional extension. If you don't want to tackle that, too, that's alright, we can merge after a rebase and open an issue describing the extension so it doesn't get lost.


fn check_non_zero_conversion(cx: &LateContext<'_>, expr: &Expr<'_>, applicability: Applicability) {
// Check if the expression is a function call with one argument
if let ExprKind::Call(func, [arg]) = expr.kind
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catches NonZeroXX::from(x) but would miss y.into::<NonZeroXX>(). Do you want to tackle that case, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the into method of NonZero does not take generic arguments. I am not sure of it. was it changed in the new update? Can you provide me with an example?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use std::num::{NonZeroU32, NonZeroU64};
fn main() {
    let x = NonZeroU32::try_from(1).unwrap();
    let _y: NonZeroU64 = x.into();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see.. we can add that to the unfixable test cases. It is a little tricky to tackle. That's why I added this one in the unfixable test cases:

    let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get());

It can be added in the future optimizations.

clippy_lints/src/non_zero_suggestions.rs Show resolved Hide resolved
@rustbot rustbot added has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Aug 30, 2024
@rustbot
Copy link
Collaborator

rustbot commented Aug 30, 2024

There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged.

You can start a rebase with the following commands:

$ # rebase
$ git pull --rebase https://github.com/rust-lang/rust-clippy.git master
$ git push --force-with-lease

The following commits are merge commits:

@rustbot rustbot added has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Aug 31, 2024
@rustbot
Copy link
Collaborator

rustbot commented Aug 31, 2024

There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged.

You can start a rebase with the following commands:

$ # rebase
$ git pull --rebase https://github.com/rust-lang/rust-clippy.git master
$ git push --force-with-lease

The following commits are merge commits:

@Samarth1696
Copy link
Contributor Author

@rustbot ready

@Samarth1696 Samarth1696 requested review from y21 and llogiq August 31, 2024 07:05
@llogiq
Copy link
Contributor

llogiq commented Sep 3, 2024

Can you remove the merge commit and instead rebase on current master?

@rustbot rustbot removed has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Sep 4, 2024
@Samarth1696
Copy link
Contributor Author

It's ready!

@bors
Copy link
Collaborator

bors commented Sep 5, 2024

☔ The latest upstream changes (presumably #12987) made this pull request unmergeable. Please resolve the merge conflicts.

@llogiq
Copy link
Contributor

llogiq commented Sep 6, 2024

r=me after rebase.

@llogiq
Copy link
Contributor

llogiq commented Sep 7, 2024

@bors r+

@bors
Copy link
Collaborator

bors commented Sep 7, 2024

📌 Commit af3346a has been approved by llogiq

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Sep 7, 2024

⌛ Testing commit af3346a with merge d9c4523...

@bors
Copy link
Collaborator

bors commented Sep 7, 2024

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: llogiq
Pushing d9c4523 to master...

@bors bors merged commit d9c4523 into rust-lang:master Sep 7, 2024
11 checks passed
@Samarth1696 Samarth1696 deleted the tests branch September 7, 2024 11:37
@Samarth1696 Samarth1696 restored the tests branch September 7, 2024 12:24
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants