(I understand that we are starting to rehash the numerous previous discussions, so I will try to be brief)
It's the same value as with the ?
operator. It reduces noise inside a function body by removing Ok
and Err
wraps which are often redundant for humans at the cost of 3 letters in a function signature. Eliminating Ok(())
is a nice bonus. Also it allows much easier migration of previously non-failing functions to failing ones, you simply slap try
, add new yeet
returns and ?
s if needed, and that's it. While today you have to haunt all returns and wrap results with Ok
.
Why would it result in churn? The old fn
s will continue to work without any changes, similarly to how you can use fn
s which return impl Future
instead of async fn
. Also if maintainers will decide to migrate their codebase to try fn
s, I think it can be done mostly automatically.
I think you want something like this: Pre-RFC: type-level sets Your example would look like this:
try fn foo() -> Result<u32, Error1 | Error2> { .. }
Making types imlicit in signatures only adds confusion and reduces flexibility. Even with async fn
s it causes issues around implicitly derived trait bounds for return type. For example, how would your proposal work with Option
or other custom types implementing the Try
trait?
UPD: I guess one can argue that try fn
is inconsistent in the sense that it should not belong to the function signature, because unlike unsafe fn
and async fn
it only change how body of the function is compiled, not it's signature (i.e. try fn foo() -> Resut<T, E> { .. }
is fully equivalent to fn foo() -> Resut<T, E> { .. }
). So for some it could make more sense to use fn foo() -> Resut<T, E> try { .. }
as a shorcut for fn foo() -> Resut<T, E> { try { .. } }
.