Hello everyone!
I'm trying to implement TryFrom
on a custom container type, but I'm getting some errors I can't make sense of. Here's a rough MVP of my problem: Rust Playground
I will admit, straight-up, that this seems like a duplicate of this post, but it never got an answer, so I'm testing the waters again! : v)
So! I have a custom container that stores a single piece of data:
struct Container<T: ?Sized> {
data: Box<T>,
}
When it holds a DST, I want to implement TryFrom
for it, to be able to emulate a 'downcast' that gives a concretely typed version of the container. I can do this by hand by implementing TryFrom
on every type I care about:
impl TryFrom<Container<dyn MyTrait>> for Container<MyStruct1> { ... }
impl TryFrom<Container<dyn MyTrait>> for Container<MyStruct2> { ... }
This compiles, but is A) very tedious and B) breaks down if someone outside my crate wanted to implement MyTrait
on their own type. This function should exist for any type implementing MyTrait
, so a blanket implementation seems like the right solution:
impl<T: MyTrait> TryFrom<Container<dyn MyTrait>> for Container<T> { ... }
But when I try to compile this, I get the following error:
error[E0119]: conflicting implementations of trait `std::convert::TryFrom<Container<(dyn MyTrait + 'static)>>` for type `Container<_>`
--> src/lib.rs:16:1
|
16 | impl<T: MyTrait> TryFrom<Container<dyn MyTrait>> for Container<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> TryFrom<U> for T
where U: Into<T>;
It says that my implementation conflicts with another blanket implementation in the core. But I don't understand where that's coming from. So, what impl
is this conflicting with? Is there some special magic with the From/Into
traits I'm getting caught up here? Any help in the right direction is appreciated!
Addendum:
I understand why implementing Into
would get you TryFrom
for free, but I don't implement Into
or From
for this type. So it shouldn't be getting the auto-generated impl from those.
And the reflexive implementation of From<T> for T
can't apply here.
T
is Sized
, so T
can't be dyn MyTrait
, so this shouldn't happen:
impl TryFrom<Container<dyn MyTrait>> for Container<dyn MyTrait>