Open GrigorenkoPV opened 1 month ago
this will result in the Future silently being dropped without polling it even once.
Why not let _ = foo().await;
?
Why not
let _ = foo().await;
?
I think the point is that if the API evolves (goes from fn() -> Result<A, B>
to async fn() -> Result<A, B>
) then the previous usage of let _
will continue to compile but now mean something different: ignoring the future instead of ignoring the Result
.
Why not
let _ = foo().await;
?I think the point is that if the API evolves (goes from
fn() -> Result<A, B>
toasync fn() -> Result<A, B>
) then the previous usage oflet _
will continue to compile but now mean something different: ignoring the future instead of ignoring theResult
.
Precisely. let _ =
does not get along well with any type changes to the return value. It's just that the Future
is the most egregious example, because accidentally dropping it significantly changes the control flow.
Oops, wrong button
You would still have a problem if the function changed from Result<T, Infallible>
to a real error you should handle.
There are also many other #[must_use]
types and functions that should be considered. I don't have any more general ideas, apart from explicit let _: Type
as you mention, but I'm sure we wouldn't want to add ignore
everywhere.
You would still have a problem if the function changed from
Result<T, Infallible>
to a real error you should handle.
Won't there be some special unwarp
for Result<_, !>
once !
geta stabilized?
Also, this is still a problem with current status quo of .ok()
.
Finally, this ACP is partially about adding #[must_use]
to .ok()
and .err()
, which is blocked on having no idiomatic way to ignore a Result
.
Won't there be some special
unwarp
forResult<_, !>
once!
geta stabilized?
Proposal
Problem statement
Result
is a#[must_use]
type, but there is no idiomatic way to ignore it. ConsiderThis will give you a warning, even if you don't care about the result. Now you have to discard it somehow.
Alternatives
One may try
but if we now change signature to
this will result in the
Future
silently being dropped without polling it even once. It doesn't help thatFuture
is a#[must_use]
type too. You can try to combat this withbut that's quite mouthful and is not something that will come to your mind right away.
The Rust community seems to have developed a trick for this situation, which is using
.ok()
. This works because this method (and the returnedOption<T>
type) is not marked#[must_use]
for some reason (unlikeis_ok()
) and is super unintuitive when you read this for the first time.Motivating examples or use cases
Quite a lot even in the rustc itself. Add
#[must_use]
toResult::ok
and see the number of errors you get.Solution sketch
Result
:.ok()
&.err()
as#[must_use]
afterignore
is stabilized.Maybe name it
ignore_result()
instead, for clarity.Links
Example of the problem with unpolled Futures (and general discussion of the situation): https://users.rust-lang.org/t/what-is-the-best-way-to-ignore-a-result/55187
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution: