-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Holistic Reform of #[must_use] Needed #2202
Comments
Your busy of course, but I'm surprised this has gone without comment, @carllerche ? If you read it prevously, perhaps I originally missed the mark on describing the problem and motivating a solution? I've now added a concrete example in the top description section. |
This looks mostly good, I think @carllerche is out on vacation right now so I'd like to wait for him. We've just been quite busy :) Thanks for writing this up! |
Thanks for that @LucioFranco , a little update hint goes a long way. 👍 |
No more mental bandwidth for this, but AFAIK the issue still remains. |
This looks like it can be closed. On current tokio 1.34, the code above triggers a warning. |
Description
There are at least 13 cases found, where
#[must_use]
attributes are not applied where they should be. The lack of a unused_must_use warnings lead users to potentially hard to find bugs. For example, currently this compiles without warning and results in a race condition:There are other cases where
#[must_use]
is redundantly applied, or with the included message being inconsistent. I propose to clean these all up across the tree in one pass, but I need agreement on the guidelines first, see below.Background: I encountered uncertainty regarding the proper application of the
#[must_use]
attribute in #2129 (comment) and later attempted #2140, which made it clear that neither Tokio nor I had a consistent approach or clear guidelines. Since this will be a bunch of small changes everywhere, its better to arrive at a clear plan here first, followed by a hopefully short PR time.Proposed Solution
Based on research including:
Rust Reference: the must_use attribute
Similar github issue: Add #[must_use] to Stream and Sink rust-lang/futures-rs#1415 Add #[must_use] to more types rust-lang/futures-rs#1600 BoxFuture / LocalBoxFuture should be marked as
must_use
rust-lang/futures-rs#2017 improved error message for unused futures rustasync/runtime#32Guidelines
As best I can tell from above research:
Apply
#[must_use = "..."]
to types that implementFuture
,Stream
orSink
.Do not apply on
fn() -> impl Future<..>
(orimpl Stream
, orimpl Sink
) orasync fn
of any return type, since rustc is able to provide must-use warnings on these already. Also do not apply to functions returning the types of (1).But, we may apply on
fn() -> Box<dyn Future>
, pin or other wrapped types, as rustc is not currently able to provide must-use warning for these.Apply consistently to
priv
orpub(crate)
types, as well aspub
.One point of prior confusion around (2) for me, is that rustdoc does show must_use attributes, but unfortunately does not fully emulate the
must_use
handling of rustc. In other words, (not/)applying must_use to functions has an effect on the rustdoc, see example in #2140. However, in the scheme of things this is a minor issue with these guidelines that can be tolerated.Recommended syntax
This is clearly subjective, but having looked at the current code base (see below) and compared with what others have done, I suggest the following unless there is a good reason to deviate:
The last comment is intended for
JoinHandle
or any other cases like it that are found.Note, per guidelines, these are almost always applied to types. I did not find a current example where we would want to apply it to a function.
See also: Attribute ordering, below.
I intend to edit the above guidelines/syntax based on further suggestions here.
In the current code base
I went hunting for missing cases via the following and checking for
must_use
on the nearby type:git grep -n -E "impl.*\s+(Future|Sink<.*>|Stream(<.*>)?|)\s+for\s+([A-Z][A-z]+)"
Based on the above rules, I temporarily added
#[must_use = "missing"]
or similar based on visibility of the types. I skipped cases where the type was only defined in tests. With this in place, searching and grouping occurrences:git ls-files | grep -E '.rs$' | xargs cat | grep -o -E "#\\[must_use.*\\]" | sort | uniq -c 1 #[must_use] 3 #[must_use = "futures do nothing unless polled"] 19 #[must_use = "futures do nothing unless you `.await` or poll them"] 13 #[must_use = "missing"] 4 #[must_use = "missing (crate)"] 7 #[must_use = "missing (priv)"] 1 #[must_use = "sinks do nothing unless polled"] 21 #[must_use = "streams do nothing unless polled"] 1 #[must_use = "streams do nothing unless you `.await` or poll them"] 1 #[must_use = "yield_now does nothing unless polled/`await`-ed"]
Attribute ordering
A related syntax question arises because the line order of these attributes is not well controlled by
rust fmt
. Usually in the current tree,#[must_use]
is placed after#[derive]
. But we also have:I suggest alphabetic order, which conveniently puts
cfg
(_attr
) at the top (e.g. if not a configured item, then the remaining attributes are irrelevant):And I would like to change those as part of updating
must_use
.The text was updated successfully, but these errors were encountered: