-
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
Adds must_not_suspend_lint
RFC
#3014
Conversation
Editorial: The title of this issue shouldn't say Bikeshed: Decorating a type with "must not await" sounds like it's forbidding you from awaiting values of that type – not from capturing values of that type while awaiting some unrelated object. However, I can't think of a better name that isn't considerably more verbose. |
Bikeshed: |
@bovinebuddha I personally think that is more confusing, since most users interact with |
bikeshed: I could see a feature like this being useful in generators and coroutines, since we also wouldn't want to hold mutexes across those yield points as well. So going for more generic language like |
|
@erickt that's a fair point. We did not consider extending the use of this attribute to be used for generators in the future, but I can see how it would be possible. I think |
@erickt My concern about going a bit lower level with the generator based name is that it has some sort of disconnect from async/await. We may want to just consider to add another version when we finally stabilize generators? |
We discussed this in the @rust-lang/lang meeting today and came to the conclusion that we would like to move this forward to the implementation stage, modulo whatever bikeshedding makes sense for the name. @rfcbot fcp merge |
Team member @nikomatsakis has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
One thing I'd like to see added to the open questions and alternatives sections: would it suffice to only support this on functions, and not on types? With I don't know if this is a good idea, or if it'd result in having to add far more annotations. I think it's worth discussing the tradeoff in the RFC. |
rust-lang/wg-async#19 is a related (but separate) idea that folks should be aware of. This is another attribute that would warn when certain functions are called in an async context. It might be worth mentioning this as a future direction in the RFC. |
@tmandry I think we should mention it in the RFC as a way to talk about other work in this area, but aren't these two separate concerns? |
Yes, they're separate, but conceptually they are related. I just think the RFC should mention it as you say. I don't mean to imply that it would be a future direction in the sense that it would build on this RFC, but that it's simply another thing we might consider doing in the future. |
that's a fair argument. since this is a bikeshed type of discussion, here are some grades I'd give different shed colors among these options:
I'm considering this my final input and will not comment on the naming issue further. |
I think there's been a lot of great discussion around the naming of this feature which lead to a lot of good options. There's two main ways to go forward from here:
I personally would like to finalize it in this stage as it would leave fewer open questions for the implementation stage. As far as deciding on a name goes, I think we should go with
I agree, that this is not the best possible option for a name, but it is certainly an acceptable one; one which fulfills the requirements of signaling the intent as well as being succinct enough to be remembered. Any further elaboration on the behavior of the lint should be a part of the warning text displayed as well as the documentation for the lint, as no name truly would be able to capture all the nuances of the complex conditions in which the lint would be a valid warning. |
It's been almost ten days since the last discussion on this PR, therefore in the interest of moving the RFC forward, I think we should finalize on name for the lint to be |
why not drop the word |
@SOF3 that's in order to keep parity with the |
For some more bikeshedding (which is orthogonal to this RFC, and thus I don't think passage of this), we could try to make things more generic, and instead deprecate |
(I checked @withoutboats's box, as they're not active on lang team at the moment.) |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
To be sure I understand this correctly -- no attempt is made at detecting "must_not_await" types that hide behind generic types, right? So this does not prevent That seems fine to me, but the RFC should call it out explicitly. It talks about false positives but does not mention false negatives. |
text/0000-must-not-suspend-lint.md
Outdated
# Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
Going through the prior are we see two systems currently which provide simailar/semantically similar behavior: |
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.
Going through the prior are we see two systems currently which provide simailar/semantically similar behavior: | |
Going through the prior art we see two systems currently which provide similar/semantically similar behavior: |
text/0000-must-not-suspend-lint.md
Outdated
} | ||
``` | ||
|
||
When used on a function, if the value returned by a function is held across an await point, this lint is violated. |
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.
What should happen if the value returned implements Copy
?
What should happen in the following two examples?
#[must_not_suspend]
fn foo() -> i32 { 5i32 }
async fn foo() {
let mut baz = 0i32; // EDIT: Fixed compile
{
let bar = foo();
baz = bar;
drop(bar);
}
my_async_op.await;
println!("{:?}", baz);
// Ok or not?
}
#[must_not_suspend]
fn foo() -> i32 { 5i32 }
fn qux(a: i32) -> i32 { a }
async fn foo() {
let bar = qux(foo());
my_async_op.await;
println!("{:?}", bar);
// Ok or not?
}
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.
The relevant question is whether the value is used again after an await
. EDIT: nevermind, my answer for Copy
doesn't affect that at all.Copy
is the same as for the other examples
As for your examples, I don't know of a use case for supporting the attribute on functions and would prefer to only support it on types for now.
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.
attribute on functions
I was only using the functions to obtain a value with must_not_suspend
.
Copy
doesn't affect that at all
The thing about Copy
is that when you have one value, you can easily end up with two, three, or more values resulting from copying the original value.
My question is basically will the copies will inherit the must_not_suspend
?
- If they do, are we just going to make all functions that take
must_not_suspend
values return results that are alsomust_not_suspend
? Otherwise, would we makeCopy
special and why? - if they don't, then it will become easy to shoot oneself in the foot again if one doesn't realize that they copied a value before an
await
The same logic could apply to Clone
, but it's not much of a problem there because having to write out the .clone()
makes things obvious.
my answer for
Copy
is the same as for the other examples
So I guess that means the must_not_suspend
DOES inherit across unmarked functions from the parameters to the return value?
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.
My question is basically will the copies will inherit the must_not_suspend?
If we limit the behavior to just the types, then the copies will inherit the behavior, since any instance of a type marked #[must_not_suspend]
should not be suspended across await points. I think of it as less inheriting behavior, and more applying behavior applicable to an instance of the type. I'll update the doc to reflect this.
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
I merged this, but I must have messed up the merge commit somehow. Closing manually. |
Rendered
Pre RFC discussion
must_not_await
lint wg-async#16Status
Merged!