News

Rust proposal would make derive Copy imply Clone and equality traits

Rust may be ready to let `Copy` carry the boilerplate, but only if the compiler can do it without surprising anyone.

Nina Kowalski··5 min read
Published
Listen to this article0:00 min
Rust proposal would make derive Copy imply Clone and equality traits
Photo illustration

Rust's most familiar little trait often drags a caravan of boilerplate behind it. A June 4 Rust Internals thread asks whether `#[derive(Copy)]` should also cover the companion traits developers usually add by habit, especially `Clone`, and perhaps the obvious equality and ordering pairings too. The pitch is not to make the language magical, but to formalize repetition that already feels implied in everyday code.

The boilerplate problem hiding in plain sight

The opening example in the thread lands because it mirrors code many Rust developers write without thinking twice. A derive line that once looked like `#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]` could, in principle, shrink to something like `#[derive(Eq, Ord, Copy, Hash)]` if the compiler were able to infer the rest in a controlled way. That is a small visual change with a large ergonomic effect, especially in the kind of plain data types that make up a lot of Rust APIs.

That is the real appeal here. The proposal is not about inventing a new kind of trait behavior, but about trimming away the repeated declarations that show up around simple value types, wrappers, and other structs whose semantics are already obvious from their shape. When a type is clearly meant to be copied by value, the repeated derive list starts to feel less like precision and more like ceremony.

Why `Copy` keeps showing up with `Clone`

The strongest case in the thread centers on the pairing people already assume. `Copy` sits on top of `Clone`, so when a type is marked copyable, the matching clone implementation is usually not a conceptual decision at all, it is just part of getting the trait set into a usable state. In practice, that means a lot of little structs, IDs, handles, and other lightweight data types end up with both derives every time.

That is why the thread reads like a language ergonomics discussion rather than a syntax tweak. Developers are not asking Rust to guess wildly about behavior; they are asking whether the compiler can recognize the same repetitive pattern humans already recognize when they scan a type definition. In everyday APIs, that would mean fewer derive annotations on the kinds of types that pass freely through function boundaries, get copied into state machines, or get embedded in other structs without ceremony.

  • A plain data wrapper does not usually need a dramatic trait story.
  • A small newtype around an identifier often wants copy semantics and cloning by default.
  • A simple API type that is meant to be cheap to pass around usually ends up with the same family of derives over and over.

Equality and ordering make the proposal broader

The thread does not stop at `Clone`. It also opens the door to the more obvious trait pairs, such as `PartialEq` and `Eq`, and `PartialOrd` and `Ord`, which often travel together when a type has a clear total ordering or straightforward equality semantics. That matters because these pairings are another source of repetitive boilerplate in Rust codebases, especially for structs that are really just aggregates of comparable fields.

The value of bundling them is not that Rust would become less explicit in meaning. It is that the language could encode a common pattern once, instead of forcing developers to restate it every time they write a data type that fits the pattern. For many everyday APIs, that could make the difference between a type declaration that reads cleanly and one that starts to look like a wall of trait names before the actual fields even begin.

The hard part is not the idea, it is the guarantee

The thread quickly moves into the territory that makes Rust design so careful. One response points out that this is not a trivial trait-solver trick, because if the compiler starts treating one derive as a source of several implied implementations, it has to avoid clashes with explicit manual impls and with other derives. That is a real constraint, because Rust’s trait system depends on predictability, and implied behavior can become confusing fast if it is not tightly bounded.

From there, the discussion turns toward possible compiler-level mechanisms. One idea is to syntactically omit generated impl blocks under the right conditions, which would let the compiler save boilerplate without making the trait system feel fuzzy. Another is that any semantic change might need an edition-aware transition if it risks breaking existing code, which is exactly the kind of compatibility caution Rust tends to bring to questions of language evolution.

What this would mean for everyday Rust code

The practical upside is easy to see in the kinds of code Rust developers write all the time. A type that exists mainly to carry data through an API would no longer need to spell out the same obvious trait cluster in full, and the derive line would better reflect the actual intent of the type. That is appealing not because typing is expensive, but because repeated ceremony creates noise right where readers are trying to understand the shape of a type.

Still, the thread shows that the community is not chasing terseness for its own sake. The real question is whether Rust can make common trait combinations less repetitive while preserving the language’s extremely strong guarantees about what the compiler is and is not allowed to infer. That tension is classic Rust: reduce the obvious clutter, but do not blur the contract.

Rust's familiar little trait still drags that caravan of boilerplate, and the proposal is asking whether the language should finally acknowledge the pattern. If the compiler can trim the obvious repetition without making the next derive line feel like a surprise, this would be one more small step toward Rust code that reads as cleanly as it already behaves.

This article was produced by Prism’s automated news system from verified source data, official records, and press releases, then run through automated quality and moderation checks before publishing. The system is built and supervised by the people who set the standards it runs under. Read our full AI policy.

Did this article answer your question?

Discussion

More Rust Programming News