I have created a trait for transforming from some values to a type I need. That conversion is already covered by From
/Into
for many types, but not everything I want. I thought I could exploit this, but quickly got an error "upstream crates may add a new impl of trait".
(stripped-down example in the playground)
pub trait Cookable {
fn cook(self) -> (String, Vec<i8>);
}
impl<T: Into<Vec<i8>>> Cookable for T {
fn cook(self) -> (String, Vec<i8>) {
(String::from("simple"), self.into())
}
}
impl Cookable for &str {
fn cook(self) -> (String, Vec<i8>) {
(String::from("smelly"), vec![self.len()])
}
}
That triggers the following error:
error[E0119]: conflicting implementations of trait `Cookable` for type `&str`:
--> src/lib.rs:11:1
|
5 | impl<T: Into<Vec<i8>>> Cookable for T {
| ------------------------------------- first implementation here
...
11 | impl Cookable for &str {
| ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&str`
|
= note: upstream crates may add a new impl of trait `std::convert::From<&str>` for type `std::vec::Vec<i8>` in future versions
I am worried that the only way to work around this error is to specify individual trait implementations for every one of the types that already has an Into
.
It's not a problem you can "work around". It's a limitation imposed by the compiler to prevent future changes to your dependencies from subtly changing the behavior of your code.
For now, you avoid the error by implementing for concrete types instead of using generics and traits. A macro is one way to reduce the amount of keyboard entry you have to do.
In the future, some form of specialization might also be useful to solve this. However, this sits squarely in the middle of the reason that specialization isn't stable. It's possible to use this type of specialization to create unsound Rust using only safe code. A reduced form of specialization is being worked on, but it deliberately eschews the ability to specialize based on a trait and only works for concrete types.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With