You’ll have to provide a way to adjudicate who is allowed to be the glue crate that guarantees there can only be one such crate. I don’t know of any way other than the way we have now - ‘one of the two crates involved depends on the other one and provides the impls.’
Consider the case in which two different chrono_serde and serde_chrono crates are uploaded to crates.io, and both become popular in the ecosystem. Both provide an impl Serialize for DateTime. The types in these impls are identical, there’s no way to make them coherent. These crates present a hard split in the ecosystem - my dependency tree cannot include both of them. Every time someone provides an orphan impl, it represents a potential hard split in the ecosystem. This is so much worse than what we have now.
There are three properties it would be desirable for the language to have, and you get to choose two:
- Impls do not need to be specifically imported (e.g. you only need to have
Extend and HashMap in scope to merge two hashmaps, you don’t also need to import the specific impl block).
- When you build any two libraries together, you do not get coherence errors.
- Anyone can implement any trait for any type.
Rust chose the first two. We could consider dropping the second for the third, but I think the second is clearly superior to the third.
This is definitely true, but we’re up against like the fundamental laws of information theory or something, so all we can do is find ways to mitigate it.