Proposal
Problem statement
The standard library uses specialisation to speed up certain operations like data structure cloning or slice filling in cases where the Clone implementation is equivalent to a copy. As evidenced by cases like hashbrown doing the same thing on nightly, it would be helpful for user crates to be able to do this, too.
Unfortunately, even if specialisation were stabilised, this would still not be possible on stable. Since rust-lang/rust#135634, std uses the TrivialClone marker trait for this specialisation, which is automatically implemented by user types that use #[derive(Clone, Copy)]. Thus, TrivialClone must not be stabilised, since that would make removing #[derive(Clone, Copy)] in favour of a manual implementation a breaking change1.
Solution sketch
Introduce a needs_clone function that returns false only if Clone is definitely side-effect-free:
// in core::mem
const fn needs_clone<T: CloneToUninit + ?Sized>() -> bool;
Just like the presence of a side-effect-free Drop can be detected with needs_drop this would allow user code to skip calling clone in favour of performing a bitwise copy by branching on the return value.
Alternatives
Stabilise TrivialClone, but only allow it in specialisation bounds.
Links and related work
Proposal
Problem statement
The standard library uses specialisation to speed up certain operations like data structure cloning or slice filling in cases where the
Cloneimplementation is equivalent to a copy. As evidenced by cases likehashbrowndoing the same thing on nightly, it would be helpful for user crates to be able to do this, too.Unfortunately, even if specialisation were stabilised, this would still not be possible on stable. Since rust-lang/rust#135634,
stduses theTrivialClonemarker trait for this specialisation, which is automatically implemented by user types that use#[derive(Clone, Copy)]. Thus,TrivialClonemust not be stabilised, since that would make removing#[derive(Clone, Copy)]in favour of a manual implementation a breaking change1.Solution sketch
Introduce a
needs_clonefunction that returnsfalseonly ifCloneis definitely side-effect-free:Just like the presence of a side-effect-free
Dropcan be detected withneeds_dropthis would allow user code to skip callingclonein favour of performing a bitwise copy by branching on the return value.Alternatives
Stabilise
TrivialClone, but only allow it in specialisation bounds.Links and related work
TrivialClone: stop specializing onCopyrust#135634Footnotes
And even if
TrivialClonewere implemented differently, this would still be a major semver-hazard. ↩