Yes, that's correct. The primary aim of the rules is to forbid <external, external>
implementations, but they have been reformulated into allowing the complement <local,any> | <any,local>
.
One thing that makes the orphan rules tricky to understand is that they primarily prevent forward-compatibility problems: To really see them in action, you have to consider not just what the code looks like today, but also what it might look like tomorrow.
Let's say that we have three crates, a
, b
, and c
and look at impl a::Tr for b::Ty
:
It can appear in a
, because a::Tr
is local. It can also appear in b
, because b::Ty
is local. The two crate authors need to agree between themselves who gets to provide the implementation— If they both do, the compiler will error out.
Under the orphan rules, c
is never allowed to provide this implementation because both the trait and type are foreign. Without the orphan rules, c
could provide this implementation as long as neither a
nor b
does, but that can cause problems:
Another crate d
would necessarily be able to also provide an implementation, which will also work just fine. Right up until some project wants to include both c
and d
as dependencies, which will then fail to compile because of the conflicting implementation.
Also, If the authors of a
and b
later agree that the trait implementation makes sense to provide, one of them will want to add the implementation. This, though, would break any program that relied on c
, because there are now duplicate implementations in play. So we are now in an awkward impasse where the implementation in c
is preventing the authors of a
and b
from adding functionality that they would like to, and might even be a critical need for some users that can't pull in c
as a dependency for some reason.
The solution that Rust came up with for this problem is to forbid the implementation in c
(and d
and e
...) entirely, so that the authors of a
and b
just need to coordinate with each other instead of (potentially) every third-party crate author that happens to rely on both a
and b
.