Say I have some code that removes a file:
fn main() {
delete();
}
fn delete() -> std::io::Result<()> {
std::fs::remove_file("notes.txt")
}
If I try to compile this code, I get a warning telling me there's a Result
that must be used:
warning: unused `std::result::Result` that must be used
--> src/main.rs:2:5
|
2 | delete();
| ^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
Great! But let's say I don't care if an Err
is returned. I can suppress the warning by discarding the return value:
let _ = delete();
From a bit of searching, it seems like this is the recommended way to ignore a Result
. However, I recently encountered an issue that's making me rethink this. Say I refactor my program to be asynchronous:
#[tokio::main]
async fn main() {
let _ = delete();
}
async fn delete() -> std::io::Result<()> {
tokio::fs::remove_file("wow").await
}
The problem here is that I'm no longer ignoring a Result
; I'm ignoring a Future
. So the program will exit without awaiting on the Future
returned by delete
, the file won't be removed, and the compiler won't give me any warning.
I've seen some people use result.ok()
instead of let _ = result
. This would work better in this example because the compiler would throw an error, complaining that there's no ok
method for the Future
.
Should I be using Result::ok
to ignore a Result
? Or is there some way to tell the compiler "hey, don't warn me if there's an unused Result
but do warn me if there's some other type that's marked as must_use
"?