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

unused_io_amount captures Ok(_)s #12005

Merged
merged 1 commit into from Jan 21, 2024
Merged

unused_io_amount captures Ok(_)s #12005

merged 1 commit into from Jan 21, 2024

Conversation

m-rph
Copy link
Contributor

@m-rph m-rph commented Dec 24, 2023

Partial rewrite of unused_io_amount to lint over Ok(_) and Ok(..).

Moved the check to check_block to simplify context checking for expressions and allow us to check only some expressions.

For match (expr, arms) we emit a lint for io ops used on expr when an arm is Ok(_)|Ok(..). Also considers the cases when there are guards in the arms and if let Ok(_) = ... cases.

For Ok(_) and Ok(..) it emits a note indicating where the value is ignored.

changelog: False Negatives [unused_io_amount]: Extended unused_io_amount to catch Ok(_)s in If let and match exprs.

Closes #11713

r? @giraffate

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Dec 24, 2023
@m-rph
Copy link
Contributor Author

m-rph commented Dec 24, 2023

PS, sorry for the double PR, I couldn't open the previous after closing the fork :/

@m-rph m-rph closed this Dec 27, 2023
@m-rph m-rph deleted the 11713 branch December 27, 2023 14:56
@m-rph m-rph restored the 11713 branch December 27, 2023 15:07
@m-rph m-rph reopened this Dec 27, 2023
/// We need to check that read/write call sizes are handled.
/// We need to be careful with this to avoid false positives.
/// If we do the check directly on Expr, we will miss cases like:
/// `
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// `
///

Typo? :)

Copy link
Member

Choose a reason for hiding this comment

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

Ah wait, I'm not sure it's a typo. If you want a code block, why not use ```?

Copy link
Member

Choose a reason for hiding this comment

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

This seems to be just a self-note for Quinn specifically (at least, it seems like it isn't finished). I would suggest removing it, or making it clearer =^w^=

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 comments need to be cleaned up a bit 😬

Copy link
Member

@GuillaumeGomez GuillaumeGomez left a comment

Choose a reason for hiding this comment

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

Apart from the typo in the comment, looks good to me. Big 👍 for the comments!

@GuillaumeGomez
Copy link
Member

Let's assign someone else as reviewer too.

r? @blyxyas

@rustbot rustbot assigned blyxyas and unassigned giraffate Jan 12, 2024
@blyxyas
Copy link
Member

blyxyas commented Jan 12, 2024

A month without reviewing anything, I'll do my best =^w^=
My skills may have rusted a little bit...

...I'm such a comedian

Comment on lines 63 to 73
///
/// Here's what we will do:
/// 1. Get the callsite Expr
/// 2. Check if it's a call to read/write
/// 3. Decide whether it should be linted based on the surrounding context, e.g. arms in a match
/// statement, etc
/// 4. Lint if necessary
/// This is different to the current impl. Current impl which is limited in the match statements it
/// catches and doesn't catch cases where match is just returned.
///
/// We will use logic similar to
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 just re-read this. I will clean it up.

Copy link
Member

@blyxyas blyxyas left a comment

Choose a reason for hiding this comment

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

Meow meow (=^‥^=) Pretty good iteration, just some minor changes (performance changes that may or may not actually improve performance, but improve readability nonetheless UwU)

/// We need to check that read/write call sizes are handled.
/// We need to be careful with this to avoid false positives.
/// If we do the check directly on Expr, we will miss cases like:
/// `
Copy link
Member

Choose a reason for hiding this comment

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

This seems to be just a self-note for Quinn specifically (at least, it seems like it isn't finished). I would suggest removing it, or making it clearer =^w^=

Comment on lines 101 to 105
if let Some(exp) = block.expr {
match exp.kind {
hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, _) => check_expr(cx, exp),
_ => {},
}
Copy link
Member

Choose a reason for hiding this comment

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

Meow (just some formatting to make code more readable :D)

Suggested change
if let Some(exp) = block.expr {
match exp.kind {
hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, _) => check_expr(cx, exp),
_ => {},
}
if let Some(exp) = block.expr
&& matches!(exp.kind, hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, _)) {
check_expr(cx, exp)
}

clippy_lints/src/unused_io_amount.rs Outdated Show resolved Hide resolved
Comment on lines 162 to 173
is_okay_pat(cx, pat)
&& matches!(
pat.kind,
PatKind::TupleStruct(
_,
[hir::Pat {
kind: PatKind::Wild,
..
}],
_
)
)
Copy link
Member

Choose a reason for hiding this comment

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

As is_okay_pat is only used here, you could make it a single function to avoid matching for pat.kind -> PatKind::TupleStruct twice.

Suggested change
is_okay_pat(cx, pat)
&& matches!(
pat.kind,
PatKind::TupleStruct(
_,
[hir::Pat {
kind: PatKind::Wild,
..
}],
_
)
)
if let PatKind::TupleStruct(ref path, [inner_pat], ddp) = pat.kind
&& is_res_lang_ctor(cx, cx.qpath_res(path, inner_pat.hir_id), hir::LangItem::ResultOk)
&& matches!(inner_pat, hir::Pat { kind: PatKind::Wild,
.. }) {
// [...]
}

You can also keep the is_okay_pat function, but make it return inner_pat (using #[inline])

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 decided to merge them as adding the dotdot check would be easier.

clippy_lints/src/unused_io_amount.rs Outdated Show resolved Hide resolved
}
}
for span in wild_cards {
diag.span_note(*span, "io bytes are ignored");
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm I'm not sure if this should be "io", "IO", or "I/O".

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 prefer I/O to be honest 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is that anything capitalized breaks guidelines 😅

Copy link
Member

@blyxyas blyxyas Jan 14, 2024

Choose a reason for hiding this comment

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

I'll talk about this in Zulip. The style guide does indeed say:

  • Error, Warning, Note, and Help messages start with a lowercase letter and do not end with punctuation.

But, "I/O" is an acronym... And using io would break the first style convention imo...

Copy link
Member

Choose a reason for hiding this comment

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

It seems like there's an unanimously support for "I/O". Could you change it =^w^=

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course! what should I do about the style check :D ?

Copy link
Member

@blyxyas blyxyas Jan 14, 2024

Choose a reason for hiding this comment

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

? What style check? Like, the x test tidy in upstream Rust CI?

Copy link
Contributor Author

@m-rph m-rph Jan 14, 2024

Choose a reason for hiding this comment

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

running cargo test with "I/O" results in the test suite failing because of the style check failing because of capitalisation of "I/O". I could reword the note if that's okay with you.

Copy link
Member

Choose a reason for hiding this comment

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

Yep, reword it if that's happening. I've tried using cargo test in this PR, and apart from having to bless the .stderr files and rename the //~ NOTE: annotations, everything went just fine. ¯ \ _ (ツ) _ / ¯

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you think of this:

match s.write(b"test") {
    //~^ ERROR: written amount is not handled
    Ok(_) => todo!(),
    //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
    Err(_) => todo!(),
}

@blyxyas
Copy link
Member

blyxyas commented Jan 14, 2024

Quinn... Could you not rebase until the final approval =*w*= now I don't know what was changed in that rebase :( (no biggie, don't worry, just for the next time)

Copy link
Member

@blyxyas blyxyas left a comment

Choose a reason for hiding this comment

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

Just a nit, and this should be merge-ready =^w^=

while let hir::ExprKind::MethodCall(path, receiver, ..) = expr.kind {
if matches!(
path.ident.as_str(),
"or" | "or_else" | "ok" | "expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" | "is_ok" | "is_err"
Copy link
Member

Choose a reason for hiding this comment

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

I've looked up the frequency for each of these methods in GitHub search. Here are the results:

Search query No. of files (GitHub)
.or( 69.1k
.or_else( 102k
.ok( 565k
.expect( 1.5M
.unwrap( 2.6M
.unwrap_or( 635k
.unwrap_or_else( 567k
.is_ok( 356k
.is_err( 312k

Could you rearrange the options to avoid useless lookups? (e.g. unwrap will be much more frequent than or_else, so let's avoid looking for it first)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How silly would it be if we created a lint for this? 🤣 like, it would be beneficial even if its only usecase is dogfood tests 🤣.

Copy link
Member

Choose a reason for hiding this comment

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

Hmmmm maybe not a lint, but a PR (and taking this into account for future merges) would probably help.
Doing something similar with the methods/mod.rs file probably would benefit performance. But we would need to do some benchmarks.

If you want to do this, I'll use all our benchmarking infrastructure to verify the results.

Copy link
Member

@blyxyas blyxyas left a comment

Choose a reason for hiding this comment

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

LGTM, thanks! ❤️
Could you squash these commits into one?

Partial rewrite of `unused_io_account` to lint over Ok(_).

Moved the check to `check_block` to simplify context checking for
expressions and allow us to check only some expressions.

For match (expr, arms) we emit a lint for io ops used on `expr` when an
arm is `Ok(_)`. Also considers the cases when there are guards in the
arms. It also captures `if let Ok(_) = ...` cases.

For `Ok(_)` it emits a note indicating where the value is ignored.

changelog: False Negatives [`unused_io_amount`]: Extended
`unused_io_amount` to catch `Ok(_)`s in `If let` and match exprs.
@blyxyas
Copy link
Member

blyxyas commented Jan 21, 2024

@bors r+

@bors
Copy link
Collaborator

bors commented Jan 21, 2024

📌 Commit f73879e has been approved by blyxyas

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Jan 21, 2024

⌛ Testing commit f73879e with merge f1eade1...

bors added a commit that referenced this pull request Jan 21, 2024
`unused_io_amount` captures `Ok(_)`s

Partial rewrite of `unused_io_amount` to lint over `Ok(_)` and `Ok(..)`.

Moved the check to `check_block` to simplify context checking for expressions and allow us to check only some expressions.

For match (expr, arms) we emit a lint for io ops used on `expr` when an arm is `Ok(_)|Ok(..)`. Also considers the cases when there are guards in the arms and `if let Ok(_) = ...` cases.

For `Ok(_)` and `Ok(..)` it emits a note indicating where the value is ignored.

changelog: False Negatives [`unused_io_amount`]: Extended `unused_io_amount` to catch `Ok(_)`s in `If let` and match exprs.

Closes #11713

r? `@giraffate`
@bors
Copy link
Collaborator

bors commented Jan 21, 2024

💔 Test failed - checks-action_test

@blyxyas
Copy link
Member

blyxyas commented Jan 21, 2024

... This is the second time today... The MacOS runner is doing weird things

@bors retry

@bors
Copy link
Collaborator

bors commented Jan 21, 2024

⌛ Testing commit f73879e with merge 64d08a8...

@blyxyas
Copy link
Member

blyxyas commented Jan 21, 2024

...
@bors retry

@bors
Copy link
Collaborator

bors commented Jan 21, 2024

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: blyxyas
Pushing 64d08a8 to master...

@bors bors merged commit 64d08a8 into rust-lang:master Jan 21, 2024
5 checks passed
@bors
Copy link
Collaborator

bors commented Jan 21, 2024

⌛ Testing commit f73879e with merge 64d08a8...

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.

unused_io_amount does not fire on match file.write() { Ok(_) }
6 participants