# Why can't I \`impl\<E\> From\<E\> for EzError where E: StdError + Send\`?

**URL:** <https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857>\
**Category:** Uncategorized\
**Created:** [August 14, 2016, 6:04pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857 "2016-08-14T18:04:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [August 14, 2016, 6:04pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/1 "2016-08-14T18:04:44Z")

</div>

I’ve spent a lot of time now trying to make libraries that simplify Rust’s error handling, and am super frustrated. It feels like things fit together in ways that require needless complexity for the end user. I am constantly being thwarted and forced to add extra conversion methods and special cases to work around the type system. You may be aware of my [error-chain](https://brson.github.io/error-chain/error_chain/index.html) crate, which I think is the easiest way to deal with errors in Rust today - and it is still really complicated and requires users to understand how to do conversions correctly in several cases.

What I’ve been trying to do today is create the simplest possible library for dealing with errors correctly, one that doesn’t require newbies to understand details of all the traits and conversions around Error. The obvious way to do this is to use boxed `Error + Send` everywhere, but I can’t figure out how to do it.

Here’s some really simple code that would make `?` automatically convert `Result` of any type implementing `Error` into a local error type. Of course it doesn’t work.

```rust
use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::io::{self, Write};
use std::fmt;

pub type EzResult<T> = StdResult<T, EzError>;

#[derive(Debug)]
pub struct EzError(Box<StdError + Send>);

impl StdError for EzError {
    fn description(&self) -> &str { self.0.description() }
    fn cause(&self) -> Option<&StdError> { self.0.cause() }
}

impl fmt::Display for EzError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) }
}

impl<E> From<E> for EzError
    where E: StdError + Send
{
    fn from(e: E) -> EzError {
        EzError(Box::new(e))
    }
}

```

Try to compile this and there’s a conflicting implementation in core. What is that impl?

Is there any way to make `?` automatically box any Error?

---

<div class="post-metadata">

**Author:** ![japaric](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/japaric/32/28_2.png) [@japaric](https://internals.rust-lang.org/u/japaric)\
**Post date:** [August 14, 2016, 6:15pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/2 "2016-08-14T18:15:29Z")

</div>

> [@brson](#):
>
> What is that impl?

Probably this one:

```rust
libstd/error.rs:impl<'a, E: Error + 'a> From for Box<Error + 'a> {

```

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [August 14, 2016, 6:24pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/3 "2016-08-14T18:24:36Z")

</div>

Oh, hey, that highlights what may be the biggest problem with the Error design - not requiring Send. If that impl had the Send bound on it presumably I could do something generally useful with it. Types that don’t implement Send in Rust are special - and hostile to other types.

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [August 14, 2016, 6:26pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/4 "2016-08-14T18:26:41Z")

</div>

Perhaps I can try to use that impl to stuff types into thread-local storage and create a sendable handle to them…

Or maybe just convert them to strings, though that destroys chaining.

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [August 14, 2016, 6:30pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/5 "2016-08-14T18:30:13Z")

</div>

OK, I know. I can convert all errors to strings while simultaneously traversing the chain and converting the entire chain to strings. Converting all errors to being stringly-typed but preserving the causes. Maybe even stuff type-id’s into them for doing type-based error dispatch.

---

<div class="post-metadata">

**Author:** ![eddyb](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eddyb/32/8411_2.png) [@eddyb](https://internals.rust-lang.org/u/eddyb)\
**Post date:** [August 14, 2016, 6:36pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/6 "2016-08-14T18:36:18Z")

</div>

> [@japaric](#):
>
> Probably this one:

Except the error is "conflicting implementations of trait `std::convert::From<EzError>` for type `EzError`", which matches the identity `impl`.

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [August 14, 2016, 8:53pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/7 "2016-08-14T20:53:44Z")

</div>

Here’s another desirable thing you can’t do because of coherence and I don’t understand why:

```rust
use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::io::{self, Write};
use std::fmt;

pub fn ez_main<F>(f: F)
    where F: Fn() -> EzResult<()>
{
    if let Err(e) = f() {
        let _ = writeln!(io::stderr(), "error: {}", e);
    }
}

pub type EzResult<T> = StdResult<T, EzError>;

#[derive(Debug)]
pub struct EzError {
    msg: String,
    cause: Option<Box<StdError + Send>>,
}

impl StdError for EzError {
    fn description(&self) -> &str { &self.msg }
    fn cause(&self) -> Option<&StdError> {
        self.cause.as_ref().map(|e| &**e as &StdError)
    }
}

impl fmt::Display for EzError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.msg.fmt(f) }
}

impl EzError {
    pub fn new<E>(e: E) -> EzError
        where E: IntoEzError
    {
        e.into_ez_error()
    }
}

pub trait IntoEzError {
    fn into_ez_error(self) -> EzError;
}

impl<'a> IntoEzError for &'a str {
    fn into_ez_error(self) -> EzError {
        EzError {
            msg: self.into(),
            cause: None
        }
    }
}

impl IntoEzError for String {
    fn into_ez_error(self) -> EzError {
        EzError {
            msg: self,
            cause: None
        }
    }
}

impl<E> IntoEzError for E
    where E: StdError
{
    fn into_ez_error(self) -> EzError {
        panic!()
    }
}

```

I can’t create one function that accepts both `&str` and any impl of `StdError`. Is there any way to do that?

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [August 14, 2016, 9:01pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/8 "2016-08-14T21:01:24Z")

</div>

I can’t find any way to create a `From` implementation that accepts any type that implements `Error` (even as a reference), and that also works with `try!`. Without this ability itseems impossible to create an error handling library that doesn’t require constant attention to conversions. That is, when dealing with `?/try!` today every input error type must have an explicit conversion to the local error type. It’s horrible for newbies. Can anybody tell me how to write a `From` conversion from a generic Error type that works with `try!`?

---

<div class="post-metadata">

**Author:** ![eddyb](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eddyb/32/8411_2.png) [@eddyb](https://internals.rust-lang.org/u/eddyb)\
**Post date:** [August 14, 2016, 9:52pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/9 "2016-08-14T21:52:26Z")

</div>

> [@brson](#):
>
> Can anybody tell me how to write a From conversion from a generic Error type that works with try!?

You can't, if the `impl` may apply to the source type as well, due to the identity `impl<T> From<T> for T`.

_Even worse_, `EzError(Box::new(e))` would result in the identity impl suddenly allocating an unnecessary linked list, instead of doing nothing every time it's called.

You would need some kind of variant of specialization, or a `where E != EzError` bound (cc @nikomatsakis).

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [August 14, 2016, 10:02pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/10 "2016-08-14T22:02:03Z")

</div>

Is it true that there is a need in a call site invisible “type-erasing” conversion? Looks like `Box<Error>` is difficult to introspect ( [https://users.rust-lang.org/t/cant-to-introspect-error-cause/6536](https://users.rust-lang.org/t/cant-to-introspect-error-cause/6536) ), so perhaps it makes sense to make a call site a bit loud?

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [August 15, 2016, 2:24am UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/11 "2016-08-15T02:24:43Z")

</div>

You _can_ get this to work, it just requires nightly and horrible hacks:

```rust
#![feature(optin_builtin_traits)]
use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::fmt;

pub type EzResult<T> = StdResult<T, EzError>;

#[derive(Debug)]
pub struct EzError(Box<StdError + Send>);

impl StdError for EzError {
    fn description(&self) -> &str { self.0.description() }
    fn cause(&self) -> Option<&StdError> { self.0.cause() }
}

impl fmt::Display for EzError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) }
}

mod private {
    pub trait NotEzError {}
    impl NotEzError for .. {}
    impl !NotEzError for super::EzError {}
}

impl<E: private::NotEzError> From<E> for EzError
    where E: StdError + Send + 'static
{
    fn from(e: E) -> EzError {
        EzError(Box::new(e))
    }
}

```

This really is the _big_ (imo) motivation for either negative reasoning or the lattice specialization rule (both would allow one to fix this in a slightly different way).

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [August 15, 2016, 2:49am UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/12 "2016-08-15T02:49:34Z")

</div>

In the past there have been problems with negative trait bounds because adding a trait implementation would become a breaking change (sort of, see [RFC #1658](https://github.com/rust-lang/rfcs/pull/1658)). However, negative equality bounds don’t have this problem at all.

Also, a more general (unstable) solution to the above problem is:

```rust
#![feature(optin_builtin_traits)]
pub trait NotSame {}
impl NotSame for .. {}
impl<T> !NotSame for (T, T) {}

// Example: usage:
trait Trait<T> {}
impl<T> Trait<T> for T {}
impl<A, B> Trait<A> for B where (A, B): NotSame {}

```

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [August 15, 2016, 9:23am UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/13 "2016-08-15T09:23:19Z")

</div>

> [@stebalien](#):
>
> impl\<T\> !NotSame for (T, T) {}

Sigh... Auto traits don't work this way, they cannot be used to emulate specialization.

```rust
#![feature(optin_builtin_traits)]
pub trait NotSame {}
impl NotSame for .. {}
impl<T> !NotSame for (T, T) {}

struct Check<T: NotSame>(T);

fn main() {
    // (u8, u8) != u16, but ((u8, u8), u16) doesn't satisfy NotSame
    let a: Check<((u8, u8), u16)>; // ERROR trait bound is not satisfied
}

```

---

<div class="post-metadata">

**Author:** ![jnicklas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jnicklas/32/414_2.png) [@jnicklas](https://internals.rust-lang.org/u/jnicklas)\
**Post date:** [August 15, 2016, 10:00am UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/14 "2016-08-15T10:00:59Z")

</div>

I really hope there is a solution to this at some point, my favourite being negative trait equality bounds (`impl<E> From<E> for EzError where E: StdError, E != EzError`). For many novice Rust programmers, handling errors via panics is the only option, because implementing proper error types with the the correct conversion logic is just too difficult.

IMO this is a much more pressing problem than making error handling prettier via `?`. What good is it to shave off a few characters in a method, if you then have to go and implement an error type, along with `impl`s for `Error`, `Display` (ugh), `Debug` (derive, but still…) and a bunch of `From` impls.

Imagine someone new to the language just coming in and wanting to write a function which does some IO and then tries to parse the result to a UTF8 string, and does this with proper error handling, without any panics. They will have to learn about `fmt`, which in return requires them to learn about traits, the `Write` trait, the `write!` macro, macros, `derive`, then come the `From` trait, generics, generic traits, and so on and so forth. This is all really complicated stuff, which takes a while to wrap your head around. Imagine someone coming from a dynlang like Ruby or Python who has never really worked with a static type system trying to understand what `From` even does and how to write implementations for it.

In the end they’ll end up with a two line function and 30 lines of boilerplate.

---

<div class="post-metadata">

**Author:** ![dhardy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhardy/32/2399_2.png) [@dhardy](https://internals.rust-lang.org/u/dhardy)\
**Post date:** [August 15, 2016, 11:15am UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/15 "2016-08-15T11:15:58Z")

</div>

Where `Send` isn’t required the result isn’t too bad, but it could certainly be streamlined (e.g. a built-in boxed `Error` type). What I came up with was this ([full source](https://github.com/dhardy/pippin/blob/master/src/error.rs)):

```rust
/// Our custom result type
pub type Result<T, E = Error> = result::Result<T, E>;

/// Our custom compound error type
pub type Error = Box<ErrorTrait>;

pub use std::error::Error as ErrorTrait;

```

then implementing `fmt::Display` and `ErrorTrait` (`description` function) for every error type.

The disadvantage of boxed errors is that special handling for specific errors is more difficult, the advantage is that generic propagation of any error is much easier (this still leaves the question of whether propagation of a generic `Error` object is more useful than a panic, now that panics can be caught — perhaps the best use is with something like `enum SomeError { ErrorA, ErrorB, Other(Box<std::error::Error>) }`).

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [August 15, 2016, 2:25pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/16 "2016-08-15T14:25:24Z")

</div>

This isn’t specialization (there’s no overlap) but yeah, I didn’t test with complicated types. You can make it work but it starts to look nasty:

```rust
pub struct Pair<A, B>(A, B); // Don't use this in your types...
pub trait NotSame {}
impl NotSame for .. {}
impl<T> !NotSame for Pair<T, T> {}

// Handle unsized wrappers one-by-one...
impl<T: ?Sized> NotSame for Box<T> {}
impl<'a, T: ?Sized> NotSame for &'a T {}
impl<'a, T: ?Sized> NotSame for &'a mut T {}
// etc...

```

Here’s the full example I’ve been playing with:

```rust
#![feature(optin_builtin_traits)]

use std::error::Error;

pub struct Pair<A, B>(A, B); // Cannot be constructed...
pub trait NotSame {}
impl NotSame for .. {}
impl<T> !NotSame for Pair<T, T> {}

// Handle unsized wrappers one-by-one...
impl<T: ?Sized> NotSame for Box<T> {}
impl<'a, T: ?Sized> NotSame for &'a T {}
impl<'a, T: ?Sized> NotSame for &'a mut T {}
// etc...

enum MyResult<T, E> {
    Ok(T),
    Err(E),
}

enum MyOption<T> {
    Some(T),
    None,
}

impl<T1, E1, T2, E2> From<MyResult<T1, E1>> for MyResult<T2, E2>
    where Pair<MyResult<T1, E1>, MyResult<T2, E2>>: NotSame,
          T2: From<T1>,
          E2: From<E1>,
{
    fn from(r: MyResult<T1, E1>) -> Self {
        match r {
            MyResult::Ok(v) => MyResult::Ok(v.into()),
            MyResult::Err(e) => MyResult::Err(e.into()),
        }
    }
}

impl<T1, T2> From<MyOption<T1>> for MyOption<T2>
    where Pair<MyOption<T1>, MyOption<T2>>: NotSame,
          T2: From<T1>,
{
    fn from(r: MyOption<T1>) -> Self {
        match r {
            MyOption::Some(v) => MyOption::Some(v.into()),
            MyOption::None => MyOption::None,
        }
    }
}

fn main() {
    let option: MyOption<u64> = MyOption::Some(1u32).into();
    let result: MyResult<(), Box<Error>> = MyResult::Err("test").into();
}

```

---

<div class="post-metadata">

**Author:** ![ahmedcharles](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ahmedcharles/32/4041_2.png) [@ahmedcharles](https://internals.rust-lang.org/u/ahmedcharles)\
**Post date:** [August 17, 2016, 5:28am UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/17 "2016-08-17T05:28:52Z")

</div>

```rust
use std::env;
use std::fs::File;
use std::io::{self, Read};
use std::path::Path;

fn read_utf8_file<P: AsRef<Path>>(path: P) -> io::Result<String> {
    let mut f = try!(File::open(path));
    let mut s = String::new();
    try!(f.read_to_string(&mut s));
    Ok(s)
}

fn main() {
    let file_name = match env::args_os().nth(1) {
        Some(n) => {
            match n.into_string() {
                Ok(n) => n,
                Err(_) => {
                    println!("File name is not valid UTF-8.");
                    return;
                }
            }
        }
        None => {
            let exe_opt = env::current_exe().ok();
            let exe = exe_opt.and_then(|p| p.file_name().map(|p| p.to_string_lossy().into_owned()));
            println!("Usage: {} <file>", exe.unwrap_or("<binary>".into()));
            return;
        }
    };
    let content = match read_utf8_file(&file_name) {
        Ok(c) => c,
        Err(e) => {
            println!("Error: {}", e);
            return;
        }
    };
    println!("{}", content);
}

```

I tried what you suggested and it seems easy enough, though that’s likely because there’s a `read_to_string` method on `Read`.

The unfortunate thing is how much code is required to have the main function not panic, while providing fairly standard error messages.

If you don’t use `read_to_string`, then you get this without doing conversions between errors (which is how `read_to_string` is implemented:

```rust
fn read_utf8_file<P: AsRef<Path>>(path: P) -> io::Result<String> {
    let mut f = try!(File::open(path));
    let mut v = Vec::new();
    try!(f.read_to_end(&mut v));
    match String::from_utf8(v) {
        Ok(s) => Ok(s),
        Err(_) => Err(io::Error::new(io::ErrorKind::InvalidData, "file did not contain valid UTF-8")),
    }
}

```

If you want to use `try!` instead of a match, then you get:

```rust
use std::env;
use std::error;
use std::fmt;
use std::fs::File;
use std::io::{self, Read};
use std::path::Path;
use std::string::FromUtf8Error;

#[derive(Debug)]
enum Utf8FileError {
    IoError(io::Error),
    Utf8Error(FromUtf8Error),
}

impl fmt::Display for Utf8FileError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Utf8FileError::IoError(ref e) => e.fmt(f),
            &Utf8FileError::Utf8Error(ref e) => e.fmt(f),
        }
    }
}

impl error::Error for Utf8FileError {
    fn description(&self) -> &str {
        match self {
            &Utf8FileError::IoError(ref e) => e.description(),
            &Utf8FileError::Utf8Error(ref e) => e.description(),
        }
    }
    fn cause(&self) -> Option<&error::Error> {
        match self {
            &Utf8FileError::IoError(ref e) => e.cause(),
            &Utf8FileError::Utf8Error(ref e) => e.cause(),
        }
    }
}

impl From<io::Error> for Utf8FileError {
    fn from(e: io::Error) -> Self {
        Utf8FileError::IoError(e)
    }
}

impl From<FromUtf8Error> for Utf8FileError {
    fn from(e: FromUtf8Error) -> Self {
        Utf8FileError::Utf8Error(e)
    }
}

fn read_utf8_file<P: AsRef<Path>>(path: P) -> Result<String, Utf8FileError> {
    let mut f = try!(File::open(path));
    let mut v = Vec::new();
    try!(f.read_to_end(&mut v));
    Ok(try!(String::from_utf8(v)))
}

```

Which, I agree is a bit much for a newbie. You don’t have to impl Error in this case, but if you’re going to go this far with the From conversions, might as well do Error too.

---

<div class="post-metadata">

**Author:** ![jnicklas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jnicklas/32/414_2.png) [@jnicklas](https://internals.rust-lang.org/u/jnicklas)\
**Post date:** [August 17, 2016, 3:27pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/18 "2016-08-17T15:27:30Z")

</div>

My example wasn’t great since I forgot that you can read to an UTF8 string directly. Basically any case where you have two separate errors and want to handle both should do just as well.

Yes, strictly you don’t have to implement `StdError`, but then why have that trait in the first place if people aren’t going to implement it? It also means that the error can’t be used with `Box<StdError>`.

It’s just a lot of learn and a lot to type for something which should be common and simple.

---

<div class="post-metadata">

**Author:** ![ahmedcharles](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ahmedcharles/32/4041_2.png) [@ahmedcharles](https://internals.rust-lang.org/u/ahmedcharles)\
**Post date:** [August 17, 2016, 8:30pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/19 "2016-08-17T20:30:22Z")

</div>

I mostly just wanted to type out the code and see what it ends up looking like.

The experience wasn’t very newbie friendly, given that I’m just writing the most basic version of ‘cat’. At some point I was returning `try!(...)` instead of `Ok(try!(...))` from the `read_utf8_file` function and the error message says that it expects type `_`, but got `std::string::String` instead. I ended up looking up the definition of `try!` and changing it to a match manually before I realized that I was missing the `Ok()` around the `try!`.

---

<div class="post-metadata">

**Author:** ![jnicklas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jnicklas/32/414_2.png) [@jnicklas](https://internals.rust-lang.org/u/jnicklas)\
**Post date:** [August 22, 2016, 3:16pm UTC](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857/20 "2016-08-22T15:16:51Z")

</div>

Another pain point similar to this one is when generic code is throwing errors defined via associated types. E.g. this:

```
trait Perform {
  type Error;
}

enum CompoundError<T> where T: Perform {
  PerformError(T::Error),
  OtherError(u32)
}

impl<T> From<T::Error> for CompoundError<T> where T: Perform {
  fn from(value: T::Error) -> Self {
    CompoundError::PerformError(value)
  }
}

```

This doesn’t compile due to coherence issues. I can’t see any other way to use `From` with generic types, other than this, unless I’m missing something. And this is a pretty annoying limitation, since many libraries (e.g. serde) have these types of generic error types. I don’t think specialization will solve this problem either, given that a type might implement several traits which could cause it to map to different `From` implementation simultaneously.

I realize that solving this problem is really hard, but it’s another example of where error conversion with `From` falls short in today’s Rust.

EDIT: playground link [https://is.gd/ZEhsNf](https://is.gd/ZEhsNf)

[Next page](https://internals.rust-lang.org/t/why-cant-i-impl-e-from-e-for-ezerror-where-e-stderror-send/3857.md?page=2)
