Skip to content

"Core" traits could not have orphan impls, even without the orphan rules #2

@Ixrec

Description

@Ixrec

By "core trait" I mean many of the traits listed in https://rust-lang-nursery.github.io/api-guidelines/interoperability.html

In particular, that means std traits like:

  • Copy
  • Clone
  • Eq
  • PartialEq
  • Ord
  • PartialOrd
  • Hash
  • Debug
  • Display
  • Default

and serde traits:

  • Serialize
  • Deserialize

Even if Rust embraced incoherence and there were no orphan rules, you still wouldn't be able to write orphan impls for most of these traits, because their implementations need to access all private fields in order to be semantically correct. Even #[derive(...)]s for these traits wouldn't work for that reason.

In the special case of Serialize and Deserialize, there's an additional reason. It's often expected that the serialized form of a type will be forward compatible with all future versions of that type. In other words, if you serialize Foo from crate foo v1.0 and many months later deserialize it into a Foo from crate foo v1.5, that should "just work". That's basically impossible to guarantee unless crate foo is in charge of providing the Serialize and Deserialize impls.

Aside from std and serde, it's very rare for a trait to need access to all fields just to be semantically correct.

So, that's why an API Guideline to tell everyone to provide impls probably is the best possible solution, at least for these particular traits.


I believe this is the biggest cause of "red herring"/"XY problem" complaints about the orphan impls, i.e. complaints that changing the orphan impls actually wouldn't solve at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions