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

Add lint for unused_result_ok #12150

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

ithinuel
Copy link

This PR adds a lint to capture the use of expr.ok(); when the result is not really used.

This could be interpreted as the result being checked (like it is with unwrap() or expect) but
it actually only ignores the result.

let _ = expr; expresses that intent better.

This was also mentionned in #8994 (although not being the main topic of that issue).

changelog: [misleading_use_of_ok]: Add new lint to capture .ok(); when the result is not really used.

@rustbot
Copy link
Collaborator

rustbot commented Jan 15, 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) soon.

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 Jan 15, 2024
@ithinuel ithinuel force-pushed the add_misleading_use_of_ok branch 2 times, most recently from 323da92 to 2893485 Compare January 15, 2024 13:12
clippy_lints/src/misleading_use_of_ok.rs Outdated Show resolved Hide resolved
let ctxt = expr.span.ctxt();
let mut applicability = Applicability::MachineApplicable;
let trimmed_ok = snippet_with_context(cx, recv.span, ctxt, "", &mut applicability).0;
let sugg = format!("let _ = {}", trimmed_ok.trim().trim_end_matches('.'),);
Copy link
Member

Choose a reason for hiding this comment

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

What does the trimming here do?

Copy link
Author

Choose a reason for hiding this comment

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

I'm not 100% sure.
I used matching_result_ok as an example.

IIUC it removes the extra spaces on cases like line 14 of the UI test sample.

Copy link
Member

@y21 y21 Jan 16, 2024

Choose a reason for hiding this comment

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

🤔 That's odd, I'm not sure what's going on in match_result_ok. The span of the receiver of the .ok() method call should always be

    x   .   parse::<i32>()   .   ok   ();
    ^^^^^^^^^^^^^^^^^^^^^^

I tried removing the trimming in both this lint and in match_result_ok and in both cases it seems to pass all tests just fine.
@flip1995 seeing that you reviewed #5032, which is where that was introduced, do you know why this was necessary?
Specifically referring to this line

Copy link
Member

Choose a reason for hiding this comment

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

No idea anymore. My suspicion is, that back then I/we cared more about well formatted suggestions. Nowadays, we don't really care about that so much, as we assume that everyone uses rustfmt anyway and Clippy suggestion formatting is not important.

But that is just a wild guess.

Copy link
Author

Choose a reason for hiding this comment

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

Is there any compatibility requirement with previous version of the compiler?

As far as I understand, _ = is a destructuring assignment introduced in 1.59.

Copy link
Member

Choose a reason for hiding this comment

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

Do you mean in the Clippy codebase or in the suggestions made by Clippy?

In the former case: no

In the latter case: Yes. If you want to add a suggestion that suggests _ = ..., it should probably be gated by an MSRV check for 1.59.0 where that feature was added. There's a lot of examples in the code of how to do that, should it be required here.

Copy link
Author

Choose a reason for hiding this comment

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

I meant the suggestion. So yes, let’s keep it as let _ = ….
I’ll let you resolve this conversation if it the required changes have been met.

@ithinuel
Copy link
Author

I discovered today that _ = … is a valid alternative to let _ = ….
Personally, I tend to prefer the lighter _ = …. However, I can see that the current code base, particularly the UI tests, heavily uses let _ = ….
I’m open to either approach, so please let me know if there is a preferred option.

@dswij
Copy link
Member

dswij commented Jan 27, 2024

FME, let _ = ... is a much more popular approach. But again, it might be only on the codebases that I've seen, and I don't have real data to back it up. IMO, It's fine to use let _ = ... for now. wdyt? @ithinuel

@ithinuel
Copy link
Author

I’ll keep it as let _ = .

I don’t think having a different recommendation based on the compiler version in used is a great things. The noise caused would outweigh the subjective readability benefits.

@ithinuel ithinuel requested review from y21 and flip1995 January 27, 2024 20:10
@y21
Copy link
Member

y21 commented Jan 27, 2024

I agree with @dswij, and FWIW, the rustc lint unused_must_use also suggests let _ = ..., so having this lint use it as well sounds good?
IMO the lint name is a bit unclear about what exactly it's looking for. What about unused_result_ok? That better captures the pattern and makes it easier if in the future we want more lints for other misleading uses of .ok(). It's also similar to match_result_ok.

@ithinuel ithinuel force-pushed the add_misleading_use_of_ok branch 2 times, most recently from beee858 to c0c5a76 Compare January 28, 2024 14:38
@ithinuel ithinuel requested a review from y21 January 29, 2024 17:15
@ithinuel
Copy link
Author

@y21 & @flip1995 is there anything blocking the PR from making it through?

Copy link
Member

@y21 y21 left a comment

Choose a reason for hiding this comment

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

Sorry for the long wait. Implementation LGTM, I just have some small documentation nits, then IMO it's merge ready? @dswij do you have something else, since you're assigned?

clippy_lints/src/unused_result_ok.rs Outdated Show resolved Hide resolved
clippy_lints/src/unused_result_ok.rs Outdated Show resolved Hide resolved
@y21
Copy link
Member

y21 commented Feb 16, 2024

We could also just add #[must_use] to the ok method in the standard library and that would cause unused_must_use to start linting on .ok(); but that might be too opinionated for unused_must_use.
I could see that leading to people who disagree with it to allow unused_must_use entirely, which would be worse because they'd miss warnings for definitely-wrong code, like string.trim(); being a no-op.

So, probably better to have it as a clippy lint instead.

@Jarcho
Copy link
Contributor

Jarcho commented Feb 16, 2024

This definitely looks like a case for #[must_use]. An unused result is either an obfuscated drop (x.ok(); will drop x), or a useless method call (foo().ok() does nothing foo() doesn't). In both cases there's a more idiomatic form to use to accomplish the goal.

@xFrednet
Copy link
Member

xFrednet commented Apr 1, 2024

Hey @y21 and @Jarcho, it looks like this PR has been approved, but there was a following discussion. Could you take a look at it?

@rustbot ready

@y21
Copy link
Member

y21 commented Apr 1, 2024

It probably makes sense to open a discussion for this on zulip. I view rustc's unused_must_use lint almost as a correctness lint since it's typically applied to things where it really doesn't make any sense to ignore it and it must be a bug (for example, ignoring futures without doing something with them is a no-op, calling .trim() on a &str without using it is a no-op), whereas using .ok() on a Result to suppress the lint is more of a style thing that people might disagree with. To give one concrete example, the dotenv crate has dotenv().ok(); in its example on the readme.

I think adding #[must_use] to ok would also lead to the suggestion let _ = result.ok(); when it could have just been let _ = result;, so a clippy lint allows for better diagnostics, though #[must_use] allows providing a message so that could be easily mitigated.

@J-ZhengLi
Copy link
Member

Well, it has been another 2 months~

so, pinging the most recent people who replies (how you don't mind): @y21 @xFrednet, anyone wanna have the privilege to open a discussion/FCP on zulip ? 😄

At the mean time, @ithinuel, sorry for the long wait, do you mind applying those suggestions made by y21 on February?

@xFrednet
Copy link
Member

xFrednet commented Jun 5, 2024

I can give this another look, if @y21 doesn't get to it during the weekend :)

@y21
Copy link
Member

y21 commented Jun 5, 2024

Sorry, missed this. Implementation wise this all still looks good to me. There's still the question if we want this in the first place.
FCP: https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/FCP.3A.20.60unused_result_ok.60

@y21 y21 changed the title Add lint for misleading_use_of_ok Add lint for unused_result_ok Jun 5, 2024
@Alexendoo
Copy link
Member

See also rust-lang/rust#66116

@xFrednet
Copy link
Member

xFrednet commented Jun 20, 2024

Hey, this is a ping from triage. @y21 I think the FCP period should be done. Can you summarize the results and move this forward?

@rustbot ready

@xFrednet xFrednet added the S-final-comment-period Status: final comment period it will be merged unless new objections are raised (~1 week) label Jun 20, 2024
@y21
Copy link
Member

y21 commented Jun 30, 2024

Looks like people are generally on board with having this be a clippy lint, based on the FCP thread. The discussion on the issue that Alexendoo linked also shows that it is a pattern that people write and would probably be too strong for rustc to warn on as part of unused_must_use for now, and it's also been tried before in rust-lang/rust#79006 and got rejected.

@flip1995 on Zulip even went as far as wanting this in the restriction category (ie allow-by-default, not style) because it's so common. I think I can get behind this, because it looks like people are still figuring out what the ideal solution for this would be and there doesn't appear to be a very clear answer on what is generally considered more idiomatic to the point where we should start pushing it onto people, but ultimately I don't have a strong preference here.
I'll post a poll soon just to get more opinions on the category

(There's also the concern that this lint will need to be deprecated when that method gets marked as #[must_use] but I don't think it's worth blocking it over that -- we had to do the same just recently with maybe_misused_cfg when check-cfg got stabilized)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-final-comment-period Status: final comment period it will be merged unless new objections are raised (~1 week) 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.

None yet

9 participants