I'm fairly new to Rust, so please excuse if this has been answered elsewhere (I can't find it)
Also apologies for lack of formatting, I can never remember how to get this forum to format code, and can't find any help about it either.
I want to define a type to deal with various kinds of error, so I tried the following:
The compiler complains that the impl for String conflicts with the generic one, because in the future someone may implemnt ErrorTrait for String.
Theoretically possible, but IMHO extremely unlikely.
So, how to work round this?
Is there no way to tell the compiler that I'm happy to take the risk of my code being broken in the future?
Grateful for any suggestions.
It's pinned but it gets unpinned whenever you take a look at it. An easy way to find it is to Search -> Only return topics/posts -> dropdown -> are pinned.
To your actual question:
There is a question which will determine how to fix this: do you intend on using the capabilities of std::error::Error?
If so, you can leverage the fact that stdlib does exactly what you're trying to do and bounce off of that: impl one and impl two.
If not, then you can rely on the fact that any T: Error must also be Display, and just work off of that:
// Your original FooError definition
impl<T: Display> From<T> for FooError {
fn from(x: T) -> Self {
Self { error: format!("{}", x) }
}
}
Note, however, that this will work for anything which is display.
One thing which might work is to combine the approaches:
// Your original FooError definition
impl<'a, T: 'a> From<T> for FooError
where Box<dyn ErrorTrait + 'a>: From<T> {
fn from(x: T) -> Self {
Self {
error: format!("{:?}", x.into())
}
}
}
However if you're performing this from call very often, it might be slightly slower, due to the use of trait objects.
No, by design. In theory everyone follows semver, and it's not a semver-breaking change to implement a trait (usually, ignoring special things like !Send [when dealing with multithreaded code] and Drop [when dealing with unions]).
152 | impl<T: Display> From<T> for FooError
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: conflicting implementation in crate `core`:
- impl<T> std::convert::From<T> for T;
I see what it's saying, but cannot see the use of the core crate conversion of any T into a T. What does this achieve, and when would it need to be done?
I also tried the 'combined' approach, which worked once I replaced x.into() with just plain x.