I don't know how to express the issue generally in the title but I have encountered a stack overflow error while defining an Error struct to handle third party library errors. Here is an example code snippet.
pub struct Error(ErrorKind);
impl From<FooError> for Error {
fn from(e: FooError) -> Self {
e.into()
}
}
impl From<BarError> for Error {
fn from(e: BarError) -> Self {
e.into()
}
}
pub enum ErrorKind {
Foo(FooError),
Bar(BarError),
Baz,
}
impl From<FooError> for ErrorKind {
fn from(e: FooError) -> Self {
Self::Foo(e)
}
}
impl From<BarError> for ErrorKind {
fn from(e: BarError) -> Self {
Self::Bar(e)
}
}
#[derive(Debug)]
pub struct FooError;
pub struct BarError;
fn main() {
let foo_e = FooError;
dbg!(&foo_e);
let _e = Error::from(foo_e);
}
When I wrote the From<T> implementation for Error type converting from a custom type e.g FooError unintentionally, I got surprised how the compiler understood the type conversion from FooError to ErrorKind then Error with a single expression e.into(). Then I moved on until I encountered a fatal error. Dived in what was the cause was and this was it. When I change the implementation to;
impl From<FooError> for Error {
fn from(e: FooError) -> Self {
Self(e.into())
}
}
The error was gone. I don't think this is intentional where compiler is missing this. If this is a bug, I would like to contribute this to the language. If not what is the casue of the error and why is this allowed by the compiler.
Any professionals help would be appreciated.
Here is the playground. Try it to reproduce the error.
Sorry for my misunderstanding. I know that the implenetation
impl From<A> for BgeneratesInto<B>. Due to this,e.into()inside the implementation is simply calling thefromfunction recursively and that causes a stack overflow error.