Yes I agree.
I don’t know about the optimizer
I think it’s different.
Suppose you wrote unsafe code which depends on your custom implementation of clone() being called. The unsafe code in this instance is not relying on any implicit contracts: it is relying on the fact that when it calls clone(), clone() will be called. If the compiler rewrites it to skip the call and Copy instead, the unsafe code violates memory safety. Who is at fault? It seems pretty clear-cut to me that it’s the compiler. What gives it the right to rewrite expressions according to the informal invariant around Clone and Copy, but not other any other traits, when there isn’t any in-language indication of Clone or Copy being special in this respect? For this to be OK I believe that we would need unsafe trait Copy, analogously to ExactSizeIterator.
Note that I’m not asking how probable, wise, or inlandish this scenario is. It’s probably not any of those things. But when thinking about language guarantees and unsafe we deal in absolutes. Overflowing the reference count of an Rc or Arc is not particularly likely either, yet we considered it a bug in need of fixing. This optimization would likewise be wrong on principle.