# Result type auto error type coersion

**URL:** <https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941>\
**Category:** language design\
**Created:** [December 9, 2022, 3:06pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941 "2022-12-09T15:06:57Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![RedIODev](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rediodev/32/10233_2.png) [@RedIODev](https://internals.rust-lang.org/u/RedIODev)\
**Post date:** [December 9, 2022, 3:06pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941/1 "2022-12-09T15:06:57Z")

</div>

## The problem:
If you use some libraries every library brings its own error type. These error types then lie outside of your crate therefore you can't coerce them with the ? operator in one function scope. You therefore then create your own enum type or struct that then implements From for all the error types (and of course std::error::Error) The problem is when you simply want to return a result:

```rust
fn foo() -> Result<i32, MyError> {
    lib1::foo()?;
    lib2::foo() //Error different error types
} 

```

## Solutions
One solution is to call lib2::foo().map\_error(MyError::From). But this is very wordy and could be very well done by the compiler. We just need a way to tell the compiler that he needs to use the From implementation. My current solution is an extention function for Result:

```rust
fn auto_err<F>(self) -> Result<T, F>
where F: From<E>;

```

This helps a lot to reduce the boilerplate of obvious from into conversions. It might even be worth a keyword but that's debatable. When it's chosen to get a keyword I would suggest the postfix ! The sample code above with the operator would look like this:

```rust
fn foo() -> Result<i32, MyError> {
    lib1::foo()?;
    lib2::foo()! 
} 

```

It might be beneficial to from/into all generic parameters of the type operated on (in this case Result).

---

<div class="post-metadata">

**Author:** ![nakacristo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nakacristo/32/10249_2.png) [@nakacristo](https://internals.rust-lang.org/u/nakacristo)\
**Post date:** [December 9, 2022, 3:28pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941/2 "2022-12-09T15:28:07Z")

</div>

Is there any problem with this?

```rust
fn foo() -> Result<i32, MyError> {
    lib1::foo()?;
    Ok(lib2::foo()?)
} 

```

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [December 9, 2022, 5:37pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941/3 "2022-12-09T17:37:58Z")

</div>

> [@RedIODev](#):
>
> ```rust
> fn foo() -> Result<i32, MyError> {
> lib1::foo()?;
> lib2::foo() //Error different error types
> } 
> 
> ```

I think the best way forward for this is the "you put `?` on everything fallible" pattern (perhaps plus `try` blocks).

Because the best answer is not "make the last one even more special with another operator", but "make the last one the same as the others":

```rust
fn foo() -> Result<i32, MyError> {
    try {
        lib1::foo()?; // it's fallible so it's `?`'d
        lib2::foo()?; // it's fallible so it's `?`'d
        lib3::foo()? // it's fallible so it's `?`'d
    }
} 

```

On stable today you can write that as

```rust
fn foo() -> Result<i32, MyError> {
    Ok({
        lib1::foo()?; // it's fallible so it's `?`'d
        lib2::foo()?; // it's fallible so it's `?`'d
        lib3::foo()? // it's fallible so it's `?`'d
    })
} 

```

---

<div class="post-metadata">

**Author:** ![RedIODev](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rediodev/32/10233_2.png) [@RedIODev](https://internals.rust-lang.org/u/RedIODev)\
**Post date:** [December 10, 2022, 8:24pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941/5 "2022-12-10T20:24:22Z")

</div>

I think after some afterthought it simply lacks a From implementation for result. Something like this:

```rust
impl<T, E, U, F> From<Result<T, E>> for Result<U, F> 
where U: From<T>, F: From<E> {
     
     fn from(source: Result<T, E>) -> Self {
          source.map(U::from).map_err(F::from)
     } 
} 

```

This would allow for:

```rust
fn foo() -> Result<i32, MyError> {
    lib1::foo()?;
    lib2::foo().into()
}  

```

Which is in my opinion pretty reasonable.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [December 10, 2022, 8:43pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941/6 "2022-12-10T20:43:24Z")

</div>

> [@RedIODev](#):
>
> Which is in my opinion pretty reasonable.

I agree, but it can't be written today because it overlaps with the identity impl.

Would be nice, though!

---

<div class="post-metadata">

**Author:** ![nakacristo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nakacristo/32/10249_2.png) [@nakacristo](https://internals.rust-lang.org/u/nakacristo)\
**Post date:** [December 10, 2022, 8:43pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941/7 "2022-12-10T20:43:54Z")

</div>

That could be nice, but it conflicts with the core `impl<T> From<T> for T;`

The possibility of a helper method was tried in [rfc 1996](https://github.com/rust-lang/rfcs/pull/1996) but finally discarded because of lack of motivation in the success conversion.

In that RFC thread @withoutboats comments about the possibility of implementing the trait:

> Someday it will work (because we want intersection impl specialization as soon as its feasible to implement it), and the impl should exist so that you can use it generically.

That was in 2017, I have no idea what that "someday" would be.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 10, 2023, 8:44pm UTC](https://internals.rust-lang.org/t/result-type-auto-error-type-coersion/17941/8 "2023-03-10T20:44:24Z")

</div>

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