-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
new lint that detects blocking operations in async #11578
Conversation
r? @Jarcho (rustbot has picked a reviewer for you, use r? to override) |
1ccb7d4
to
285d0d7
Compare
☔ The latest upstream changes (presumably #11527) made this pull request unmergeable. Please resolve the merge conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can avoid the extra HIR traversals by keeping a stack of bodies and whether that body is async. check_body
and check_body_post
would maintain the stack and check_expr
would be used to detect the calls.
You'll also need to make a distinction between async and maybe async contexts. Closures and nested functions inside an async context might run in an async context, but they may also not.
impl<'tcx> LateLintPass<'tcx> for UnnecessaryBlockingOps { | ||
fn check_crate(&mut self, cx: &LateContext<'tcx>) { | ||
// Avoids processing and storing a long list of paths if this lint was allowed entirely | ||
if is_lint_allowed(cx, UNNECESSARY_BLOCKING_OPS, CRATE_HIR_ID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lints levels can change anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Jarcho Sorry for late response, I was a bit busy dealing with other stuffs.
I'm not sure if I fully understand this phrase:
Closures and nested functions inside an async context might run in an async context, but they may also not.
So, if there's an async function like this
async fn foo() {
fn bar() {
// hehe, sleep!
std::time::sleep(INF)
}
}
Then it shouldn't trigger any warning unless the function bar
was called in foo
later, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is correct. Unless the call occurs directly within foo
there's no way to know if the function is called in an async context. Something like thread::spawn(|| sleep(10))
or thread::spawn(bar)
would be fine since the sleep
call doesn't block the current thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is correct. Unless the call occurs directly within
foo
there's no way to know if the function is called in an async context. Something likethread::spawn(|| sleep(10))
orthread::spawn(bar)
would be fine since thesleep
call doesn't block the current thread.
Ok, I think my code logic already prevent linting on such case, but I'm not sure, I'll add a few test cases tomorrow just in case
Edit: Actually, calling nested function in async function would have FN, so in the above example code, even if the bar
gets called in foo
, there wouldn't be any warnings... To lint those I'm afraid I have to loop through each body's parent, take note of the function id if there is one, then keep looping the parent to find an upper block and search every expr
inside that block until a call to the noted function id is found? And ofc ignore the calls inside thread::spawn
, but I got a feeling this whole thing could take a lot of time 🤔
☔ The latest upstream changes (presumably #11685) made this pull request unmergeable. Please resolve the merge conflicts. |
95ff7c8
to
0bf6239
Compare
☔ The latest upstream changes (presumably #11791) made this pull request unmergeable. Please resolve the merge conflicts. |
976b2a2
to
f26775c
Compare
3c822ed
to
24f6dcd
Compare
☔ The latest upstream changes (presumably #10283) made this pull request unmergeable. Please resolve the merge conflicts. |
399780b
to
6ac03a4
Compare
"std::io::copy", | ||
"std::io::read_to_string", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are only blocking if the underlying reader or writer are blocking. For example, copying between Vec
s or reading from a Vec
into a string isn't blocking in practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...only blocking if the underlying reader or writer are blocking.
That's interesting, can you further explain this?
Initially, I list those methods purely base on the observation from the tokio
crate, since there are AsyncRead
and AsyncWrite
in the crate, I assume the Read
and Write
traits from std::io
are blocking 😄 , but now that you mention it, I wonder if copying between slices would actually affect anything.
☔ The latest upstream changes (presumably #12144) made this pull request unmergeable. Please resolve the merge conflicts. |
Hey @Jarcho, this is a ping from triage. Can you give this PR a review? It's totally fine if you don't have the time right now, you can reassign the PR to a random team member using @J-ZhengLi could you rebase on master again? Since only @rustbot ready |
b1914c3
to
3194a51
Compare
yeah sure, I forgot about this one, still feel very unconfident about this one, running |
f90251e
to
607ab6b
Compare
I believe none of the lints in lintcheck use async extensively, but I could be wrong. |
☔ The latest upstream changes (presumably #12635) made this pull request unmergeable. Please resolve the merge conflicts. |
Hey, this is a ping from triage. @Jarcho can you give this PR a review? It's totally fine if you don't have the time right now, you can reassign the PR to a random team member using @J-ZhengLi Sorry for the wait, could you rebase this PR? @rustbot ready |
Looking at current implementation, combining with the other issue #4377, I kinda want to close this and maybe re-work on it later 🤔 |
fixes: #10794
changelog: new lint [
unnecessary_blocking_ops
]Ok, this is a rough one, I have no confident in many things (the name ofc), and there are certain things I wanna address before I put too much effort in it.