Where to read up on catch? What does it do?


#1

Main question

Hi, could somebody please point me to documentation on catch keyword in current Rust?

I did find RFC 0243 but that did not enlighten me too much… The RFC seems to be talking about implementation options and it doesn’t seem clear which ones have been chosen…

catch doesn’t seem to be mentioned in rust books either…

Background

There’s an ongoing discussion on the internals and one of the suggestions there is

fn foo() -> T { catch { … }} can be shortened to fn foo() -> T catch { … }

but I’m really struggling to understand what that means…

Confusion

Isn’t

fn try_foo() -> Result<i32, FooErr> {
   ...
}

fn try_abc() -> Result<i32, AbcErr> {
    Ok(try_foo()?)
}

already doing some type conversion near the question mark operator? Smth like this:

fn try_abc() -> Result<i32, AbcErr> {
    match try_foo() {
        Ok(result) => Ok(result),
        Err(fooErr) => Err(From::from(fooErr)),
    }
}

Extra Question

And how is then

fn try_abc() -> Result<i32, AbcErr> {
    Ok(try_foo()?)
}

different from

fn try_abc() -> Result<i32, AbcErr> {
    catch {
        Ok(try_foo()?)
    }
}

Thx!


#2

Catch is not yet stable, and so that’s why there’s no documentation. I haven’t kept up with how implementation is going; the RFC is all I know.


#3

Thx Steve, it seems catch isn’t yet implemented on nightly even…
Should have checked in playground
It’s still interesting to know the answer to my “Extra Question” above,
though you’re probably not the right person to enquire that from


#4

Based on my reading of that RFC:

fn try_abc() -> Result<i32, AbcErr> {
    Ok(try_foo()?)
}

The above would be expressed as:

fn try_abc() -> Result<i32, AbcErr> {
    catch {
         try_foo()
    }
}

But both of the above are really the same as just try_foo() by itself (assuming it’s Err type is AbcErr).


#5

That’s my reading as well. But does this then ever make sense?

fn some_fn(...some_param...) -> ...some_type... {
    catch {
        ...some-code...
    }
}

Does wrapping the whole body of a function in a catch ever make any difference under that RFC?

The reason I’m asking is that some participants in an internals discussion suggested literally

fn foo() -> T { catch { … }} can be shortened to fn foo() -> T catch { … }

e.g. introducing a shorthand for wrapping the whole body of an fn into catch. So I’m trying to figure out what they meant…


#6

I can see catch being useful to avoid code like:

Ok(<a bunch of really long multiline code here>)

#7

That’s exactly the bit I do not understand :frowning:
Wouldn’t one still need to wrap code into Ok even inside a catch?
In fact the RFC itself says

Before stabilizing, we should determine whether we plan to make changes to
better align this feature with a possible do notation
(for example, by removing the implicit Ok at the end of a catch block)

Hmm… implicit?.. I think I get it now… This catch works in tandem with ? I see…
Not sure I’m a big fan of that RFC then
I see how it can be useful…
But it will just take a lot of effort to settle this into my head


#8

Hmm, I was going by this statement in the RFC (emphasis mine):


#9

Catch is on nightly but in a slightly different form with do catch due to the fact that catch is not a keyword (yet) [please look at discussions around the epoch rfc]

this is how it works currently on nightly https://play.rust-lang.org/?gist=989f95262b8a258d0fab8d218d2cf1e6&version=nightly


#10

I had a hard time reconciling that playground example (thanks for that by the way!) against the RFC until I spotted https://github.com/rust-lang/rust/issues/41414 - hopefully that saves a bit of headscratching for others :slight_smile:.