[IDEA] `.catch`

We have let..else, I've been using this feature since it was on nightly, but i think there are 2 issues with it:

1- we don't have access to the actual error variant;

2- the else expression must diverge, we can't recover.

I propose an expression to replace let..else, the .catch (I'm aware this is never happening, I just want to get more opinions on this).

it would allow for both taking the error, and recovering from it, and would work similar to the .await syntax:

let value = this_may_fail().catch err {
  if err.recoverable() { fallback_value }
  else { return }

The .catch operator would be available for any type that implements std::ops::Try. so for Result<T, E> it would bind E to the pattern after the .catch, and the catch expression would need to have type T (if it evaluates to T, then it recovers, but we can also diverge)

I also do think this could be just unnecessary syntax sugar, since it can be replaced by just a match. But I still feel rust's error handling story isn't complete

This isn't directly doable with the current Try formulation, since the break case deals in the "residual" Result<!, E>, not E directly.

As a slightly more agreeable syntax, perhaps...

let value = try { this_may_fail()? } else {
    Err(err) if err.recoverable() => fallback_value,
    _ => return,

The desugar of try-else would be roughly

macro(try { $($body:tt)* } else { $($rest:tt)* }) {
    match Try::branch(try { $($body)* }) {
        ControlFlow::Continue(output) => output,
        ControlFlow::Break(residual) => match residual {

modulo temporary lifetime extension which I'm not thinking about.

Generally the operation desired here is unwrap_or_else but without the closure barrier. For a majority of cases, .or_else(|err| ..)? should be able to accomplish what's desired, in theory.


a proposal i'd seen before is:

let A(value) = v else match {
    B(b) => return b,
    C => continue,

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.