&T -> T when T: Copy

I have a struct T. It has the trait “Copy”

#[derive(Cone, Copy, Debug)]
pub struct T { ...

Now, I have a &T, and I want to create a T. What is the fastest way to do this? I can do .clone, but given I have trait Copy, there should be a faster way right?

Just dereference the reference.

let t_ref: &T = ... ;
let t: T = *t_ref;
1 Like

Derefing worked. Thanks! Issue resolved.

1 Like

“Faster” as in runtime speed? No; *t_ref and t_ref.clone() will do exactly the same thing at exactly the same speed.

1 Like

†: Only applies to builds with optimisations enabled and at a sufficient level.

Snark aside: use Copy if you can, but don’t sweat it too much.

  1. I was not aware “zero cost abstraction” went this far.

  2. I don’t doubt that you are correct, it’s not clear to me how to verify this via reading the source. Can you point me at the lines of code that shows that:

*t_ref == t_ref.clone() in terms of “cost”
for a type T: Copy ?

I think this is based on two main points:

  1. For Copy types, Clone is derived by copying. If we had a copy method of the Copy trait, we could see this as following:
impl<T> Clone for T where T: Copy {
    fn clone(&self) -> T { self.copy() }

(Of course, this is only an imaginative example)

  1. Such a trivial functions can easily be inlined by optimisations, i.e. in the calling code we’ll just copy instead of explicitly cloning.

I can’t make any proof for now - strictly speaking, we must dive into code that is derived (i.e. into the implementation of derive(Debug) attribute), but this seems to be the most reasonable.

@Cerber-Ursi : This seems like a reasonable explanation of .clone() reducing to *T for T:Copy. Thanks!