The Re-Rebalancing Coherence RFC raised an important observation about the unfortunate limitations introduced by the “orphan rule”:
A long standing pain point for crates like Diesel has been integration with other crates. Diesel doesn’t want to care about chrono, and chrono doesn’t want to care about Diesel. A database access library shouldn’t dictate your choice of time libraries, vice versa.
However, due to the way Rust works today, one of them has to. Nobody can create a diesel-chrono crate due to the orphan rule. Maybe if we just allowed crates to have incompatible impls, and set a standard of “don’t write orphan impls unless that’s the entire point of your crate”, it wouldn’t actually be that bad.
The orphan rule exists to prevent crates from producing overlapping trait implementations. If the orphan rule did not exist, then adding a new dependency to your crate could break compilation due to overlapping trait implementations in two of your dependencies.
If we could provide a special crate type dedicated to orphan implementations, though,
then only these extension crates could introduce conflicts. Such crates could take
care to provide feature flags to selectively enable/disable particular
or they could be limited to a single
impl, in order to make resolution of
such conflicts trivial.
By requiring these crates to extend an existing crate, they could potentially
even gain access to
pub(crate) implementation details, which may be necessary
for implementing external traits (although exposing
pub(crate) implementation details could
cause SemVer issues, and so might be undesirable).
This could potentially be implemented in Cargo, without any changes needed to the
Rust compiler at all. A new
[ext] crate type could be defined that essentially
injects source code into another existing
Cargo.toml could be
allow adding extension crate dependencies, perhaps using a syntax similar to
If Cargo supported this, then diesel’s
chrono feature could be moved into
[ext] crate. More importantly, though,
third party users of libraries like
chrono could write
[ext] crates to enable interoperability without needing
to branch the source code for either dependency.
If there is any interest in this, and anyone else wants to carry the torch of writing an RFC, that would be great (unfortunately, I don’t really have time to dedicate to it right now).