Centril's master plan for error handling:
Here is my current (so it's subject to change...) master plan for error handling in Rust:
-
We have
try fn
and lint inclippy
in favor of it overfn .. -> Result<..>
.EDIT: Addenda to "lint in
clippy
":@scottmcm and @rpjohnst have convinced me that linting in clippy uniformly in this way would be too agressive and that it would not be consistent / uniform with
async fn
which we would not lint for in this way since you can't always move towardsasync fn
. Sometimes, you might also want to lint towardsfn
... instead of towardstry fn
depending on the usage.As @scottmcm pointed out, we might want a more subtle:
"you used
?
andOk(
7 times each, but literally never mentionErr(
; have you considered try?"Therefore, I'm retracting my support for such an aggressive clippy lint.
-
try
andtry fn
doOk
-wrapping in the tail position.try fn foo() -> Result<usize, ()> { 1 } try { a? + b? }
-
fail
doesErr
-wrapping everywhere (fn
,try fn
,try
, ..).try fn bar() -> Result<(), usize> { fail 1; } fn bar() -> Result<(), usize> { fail 1; } try { fail 1 }
-
break
is permitted at the top level of a function.This means that the following becomes legal:
fn foo() -> usize { break 1; }
Effectively,
break
becomes the "return to the closest scope that is a stop-gap (try
,fn
,loop
,while
,for
)"This change makes transitioning from a
try
block to atry fn
easier. -
break
doesOk
-wrapping insidetry fn
andtry
.try fn foo() -> Result<usize, ()> { break 1; } try { break 1; }
-
return
doesOk
-wrapping insidetry fn
.try fn foo() -> Result<usize, ()> { return 1; }
-
there is no
pass
/ you shall notpass
.I (think) originated the idea, but I'd like to take it back... I don't like the idea anymore.
Why? Because it does not fit in the imperative-monadic framework of
return
being a sort ofpure
with early-return. Adding another keyword seems wasteful and creates problems for Ok-wrapping in the tail position. -
Optional point: adding automatic labels such as
'try
.To enable easy disambiguation between
break
toloop { .. }
and totry { .. }
, you can use the automatic label'try
withbreak 'try expr
. These automatic labels can be added for'try
,'if
,'while
,'for
,'loop
,'fn
,'match
, allowing users to build powerful macros if they wish using label-break-value.
While this system is not 100% consistent, it is as close as I got.