B: From<A> ==> Foo<B>: From<Foo<A>>


#[derive(Clone, Debug, Eq, PartialEq)]
pub struct WithBacktrace<T> {
    data: T,
}

impl<A, B: From<A>> From<WithBacktrace<A>> for WithBacktrace<B> {
    fn from(a: WithBacktrace<A>) -> Self {
        WithBacktrace {
            data: B::from(a.data),
        }
    }
}

Why doesn't this code compile and how do I fix it? The idea is that if we can do A -> B we should also be able to do WithBacktrace<A> -> WithBacktrace<B> (backtrace not actually shown in this code).

You can't do that with the From trait because it conflicts with T: From<T>. I woupd just make ot a normal method on WithBacktrace

Hmm, I asked a X-Y problem. I have error types ErrA, ErrB. I also have ErrB: From<ErrA>.

This means that we can do

fn some_func(...) -> Result<..., ErrB> {
  ... bar()? ... ; // where bar(..) -> Result<..., EerrA>```
}

So far so good, since the ? knows to use the From.

Now I'm looking at this and I want to attach a backtrace to ErrA and ErrB, so we ahve:

some_func(...) -> Result<..., WithBacktrace<ErrB>> {

   ... bar() ? ... ; // bar() -> Result<..., WithBacktrace<ErrA>>

but this doesn't compile. This is where I want the ErrB: From<ErrA> to auto give me a WithBacktrace<ErrB>: From<WithBacktrace<ErrA>>

I hope this clarifies the question.

I like to use thiserror for this sort of stuff. If you have a backtrace: Backtrace field it'll automatically create a backtrace in the From impl.

#[derive(Error, Debug)]
pub enum MyError {
    Io {
        #[from]
        source: io::Error,
        backtrace: Backtrace,
    },
}

So instead of generics, we use codegen.

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