Is Copy useful as a trait bound?

I've been doing some reading about the Copy trait, specifically about the choice to mark copy-able types with a trait instead of using a keyword (e.g. something like Swift's struct vs class).

From what I understand, traits generally have two roles - to describe an interface, and/or to enforce a contract. Copy seems to fall into the second category (considering that it's a marker trait I don't see how it could be an interface), but unlike other marker traits (e.g. Send and Sync), I've never seen Copy show up in a trait bound.

I was curious to know if any of you have seen or used Copy as a bound, and/or know of any situations where that would be useful.

1 Like

Usually Clone suffices and is more general as a trait bound, but sometimes it's useful to signal a probably-cheap operation. If in doubt I'd say use a Clone bound.

("Probably" as there's not a 1-to-1 between Copy and "cheap"; Rc/Arc are pretty cheap to clone and large arrays of copyable types may be expensive to copy.)

I don't see the utility of a keyword over a trait here though.

3 Likes

Consider this example I wrote the other day: Rust Playground

You can remove the Copy bound and see all of the errors that it produces. The compiler happily tells you to add the trait bound back. Since the function accepts numeric types, Clone doesn't really make sense, here.

1 Like

I use Copy bounds when it really doesn’t make sense for the param to be non-Copy (eg. 99% of the time a primitive type or a small simple struct) and having to sprinkle clone()s around would just make the code messy. You can always remove the bound if a use case appears later.

2 Likes

Come to think of it, here's a case where the bound is crucial and the keyword less capable.

#[derive(Copy, Clone)]
struct Generic<T>(T);

// aka
// impl<T> Copy for Generic<T> where T: Copy {}
1 Like

Oh, and another case where the bound is crucial.

4 Likes

This is exactly the kind of thing I was looking for! Thanks :slight_smile:

1 Like

https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.copy_from_slice, for example, which is the safe way to use memcpy.

1 Like

Check out some methods on slices.

Also, it can be required for soundness to ensure the lack of a destructor.

5 Likes

I use Copy as a bound in my tk crate.

It helps to eliminating boring clone()s of a trivial handler and makes APIs more ergonomic.