Ixrec / rust-orphan-rules

An unofficial, experimental place for documenting and gathering feedback on the design problems around Rust's orphan rules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow derive-generated orphan impls for traits with an "official" `#[derive(...)]`

Ixrec opened this issue · comments

commented

One reasonable response to the "Serialize is special" argument is that all of this reasoning is purely theoretical when all the user wanted to do is "put #[derive(Serialize)] on Foo because Foo's author forgot to do that". After all, #[derive(Serialize)] will generate exactly the same impl even if it's orphan-invoked, no matter how many different crates choose to orphan-invoke it, and even if Foo's author added it themselves someday.

So we could add a special exception for impls created by a custom derive from the same crate as the trait being derived, and that would be coherent for the same reasons the special rule for OIBITs/auto traits is coherent.

Of course, this gets really weird really fast since serde and serde-derive are separate crates so one would probably have to bless the other, and this technically means giving everyone access to your private fields in order to invoke the derive, and this probably blows up if Foo's author decides they needed a custom Serialize impl, and we should probably just get people to follow the Rust API Guidelines consistently enough that the derive-able traits stop causing orphan rule errors for anyone.

(I think I got this idea from https://internals.rust-lang.org/t/revisit-orphan-rules/7795/44?u=ixrec. I'm not sure if the author of that post is actually proposing this idea or not)

That would allow you to write a SetLenUnsound trait, derive it on std::Vec, and read uninitialized memory without technically writing a line of unsafe {}. Bypassing privacy whenever you want is not really an option.

Worse, Serde itself already allows you to modify arbitrary fields in any object that uses the derive implementation.