fn run(opts: Opts) -> Result<(), impl std::error::Error/*( aka Error )*/> {
if false {
let e = <Box<dyn Error> as From<&'static str>>::from("test");
return Err(e);
}
Ok(())
}
which doesn't compile because Box<dyn Error> doesn't implement Error (because its contents don't implement Sized). Is there a way to make this code work. It's just a placeholder so it doesn't really matter, but I feel it would help me to understand trait object better.
I never noticed that there's no impl Error for Box<dyn Error>. I suppose you want to return impl Error, rather than Box<dyn Error>, to hide the return type? If so, you can probably define an adapter struct (e.g. struct Adapter(Box<dyn Error>), impl Error for it, and return that.
The issue is that this implementation is missing the T: ?Sized bound to support trait objects. That should be backwards compatible to add, but I'm surprised that it hasn't been noticed before if it is really that trivial to fix...
Update: I added ?Sized to the bound and got the following error
error[E0119]: conflicting implementations of trait `core::convert::From<alloc_crate::boxed::Box<dyn error::Error>>` for type `alloc_crate::boxed::Box<dyn error::Error>`:
--> src/libstd/error.rs:219:1
|
219 | impl<'a, E: Error + ?Sized + 'a> From<E> for Box<dyn Error + 'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> core::convert::From<T> for T;
error[E0119]: conflicting implementations of trait `core::convert::From<alloc_crate::boxed::Box<dyn error::Error + core::marker::Send + core::marker::Sync>>` for type `alloc_crate::boxed::Box<dyn error::Error + core::marker::Send + core::marker::Sync>`:
--> src/libstd/error.rs:255:1
|
255 | impl<'a, E: Error + Send + Sync + ?Sized + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> core::convert::From<T> for T;
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`.
error: Could not compile `std`.
I think those conversions are unnecessary now since they are covered by the blanket impl. I will try removing them and see if I get errors.
Update 2: This causes failure so the conflict must be between 2 things that are not the same. Is this a rustc bug?
Update 3: I asked about the issue on irlo, but I don't fully understand the response. Does it mean that the conflicting impls above are redundant? It doesn't seem so since removing them causes errors elsewhere.