That has got to be the most "I didn't think this through" take ever.
While it's a known pain in the ass. Not having it is a bigger pain.
The moment you allow this, you have to find a way to pick between several implementation - and they don't always have sane names.
Orphan rules prevent this from happening.
> The moment you allow this, you have to find a way to pick between several implementation - and they don't always have sane names.
There are other possible solutions that don't involve that.
For instance, many applications would be quite happy with "There can be only one implementation", giving a compiler error if there's more than one.
A slightly more sophisticated rule would be "Identical implementations are allowed and treated as a single implementation". This would be really convenient in combination with some kind of "standalone deriving" mechanism, which would generate identical implementations wherever it was used.
And if the original poster had said that I would be ok. Instead what they said is:
> It's a great example of something I'd call "muh safety", desire for perfection and complete avoidance of all problems at all costs, even if it means significantly worse developer ergonomics.
This implies the writer didn't assume what happens if you "turn-off" orphan rules. I.e. you don't trade perfection for developer ergonomics, you trade one set of developer (ability to write any trait for any type) ergonomics for another (having to battle two incompatible trait implementations from crates you don't own).
Either you have to manually specify how nearly every implementation is pulled (horrible developer ergonomics) or, even worse, you go into monkey patching territory.
> For instance, many applications would be quite happy with "There can be only one implementation", giving a compiler error if there's more than one.
Ok. But you still need a resolution mechanism to fix the error. Which implies manually solving ambiguity. And how do you solve it for blanket implementations?
At least initially, the resolution mechanism could be "don't include more than one implementation".
To reuse the canonic example:
// crate "types"
pub struct Thing;
// crate "traits"
pub trait Action {}
// crate "alpha_v0"
impl traits::Action for types::Thing {}
// crate "beta_v1"
impl traits::Action for types::Thing {} // Doesn't exist for beta_v0
Say by transitive dependencies, alpha_v0 and beta_v0 are imported, and due to vulnerability, you upgrade beta_v0 -> beta_v1 (let's assume that trait is essential for the vulnerability resolution).Now what? You either have to skip future updates, or keep the vulnerable beta_v0 crate.