-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Error handling guide #18903
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
Error handling guide #18903
Conversation
} | ||
``` | ||
|
||
If we ever hit the third match arm, something is very, very wrong. Rust calls |
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.
I think it'd be better to use a different example for unreachable!()
. In this one unreachable!()
is used to work-around a compiler limitation and if I didn't know that when reading this, I'd be very confused by what it is you mean by something very, very wrong
.
I'll try to be constructive and come up with a better example but essentially anything where unreachable!()
specifies an invariant in the control flow that's not encoded in the types would do, I think.
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.
Is the compiler going to be able to figure this out eventually? How would it do it?
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.
Most likely not, it'd after all require incorporating a complete SMT solver the way Liquid Haskell does and it'd only work for some subset of Rust. From the user's perspective it is still, however, a compiler limitation. Maybe it is useful to mention this unreachable!()
use case separately, though. :)
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.
Then why is this a bad example? I guess I'm not seeing the distinction you're drawing here.
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.
So for example in rustc we have the ast::Expr_
enum, which enumerates all the possible expression nodes. One of the variants is ExprIfLet
, however, in most of the components of the compiler encountering a value of that variant is a contract violation because the if let
construct is desugared at a very early stage, immediately after a program is parsed.
This is the sort of a thing that I tend to use unreachable!()
for and I think it's good for: expressing paths in the control flow that should not be reached according to an implicit contract enforced in a different part of my program. This is a bit subtle but still different than using it for essentially "hacking" the compiler to accept your program.
Anyway, I am being slightly pedantic here, I just thought that we could do better here, how about something like this:
enum Event {
Rust10ShipsIn2015
}
fn probability(_: &Event) -> f64 {
0.95
}
fn descriptive_probability(event: Event) -> &'static str {
match probability(&event) {
1.00 => "certain",
0.00 => "impossible",
0.00 ... 0.25 => "very unlikely",
0.25 ... 0.50 => "unlikely",
0.50 ... 0.75 => "likely",
0.75 ... 1.00 => "very likely",
_ => unreachable!()
}
}
fn main() {
std::io::println(descriptive_probability(Rust10ShipsIn2015));
}
Feel free to cut down if you think it's a good fit.
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.
I changed things to add this :)
This looks very good, I think. I wonder if it'd also be useful to talk about downgrading panics to failures by isolating them in separate tasks. Or rather, elaborating more on the idea that tasks provide a natural boundary for panics to be isolated from other parts of a system. |
line. This allows us to handle and possibly recover from this sort of error. | ||
|
||
If we don't want to handle this error, and would rather just abort the program, | ||
we can use two methods, `ok()` and `unwrap()`: |
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.
why not use unwrap() directly?
see: http://doc.rust-lang.org/core/result/enum.Result.html#method.unwrap
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.
Ah! So, I forgot that unwrap
is on Result
too.
also, this guide overlaps with the result-docs. Maybe unify them? |
It does overlap a bunch. We should pull some of the broader stuff out of the Result docs and put it here. |
e5970ce
to
303a112
Compare
This should be good to ship, r? |
error: non-exhaustive patterns: `_` not covered [E0004] | ||
``` | ||
|
||
While we know that we've covered all possible cases, Rust can't tell. So we add |
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.
Nit: Could we maybe just point out why it is we've handled all possible cases (i.e. probability having a value between 0 and 1)?
@steveklabnik This looks very nice! A few more nits from me and I'm happy but maybe another pair of eyes would be useful too. |
303a112
to
29128ef
Compare
Updated with everything but |
``` | ||
|
||
We shouldn't ever hit the `_` case, so we use the `unreachable!()` macro to | ||
indicate this. `unreachable!()` gives a differnet kind of error than `Result`. |
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.
s/differnet/different
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.
thanks, fixed
29128ef
to
16b9f67
Compare
We currently document |
Implement implicit sized bound inlay hints
Now that we've done
fail
->panic
, I feel bringing back the error handling guide is a good idea. We had one long ago, but it was removed when conditions were removed.This doesn't cover the new FromError stuff, but I feel like it's already useful in this state, so I'm sending this PR now.