Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Rust automatically implement clone when dereference?

Tags:

rust

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl Copy for Point {}

impl Clone for Point {
    fn clone(&self) -> Point {
        *self
    }
}

When I only implement Copy, Rust tells me I need to implement Clone. When I only implement Clone, Rust tells me Point can be moved.

My question is, I have never implemented anything, This code is a bit like a circular dependency, but it works? Why?

like image 738
Kk Shinkai Avatar asked Oct 11 '25 17:10

Kk Shinkai


1 Answers

TL;DR: Copy requires Clone for convenience and Clone on a Copy type is usually implemented using a copy.


The Rust compiler will routinely have to do bit-wise copy of your data. But there are two cases:

  • If the type does not implement Copy, the original instance isn't usable anymore, your data has moved.
  • If the type does implement Copy, the compiler knows that it's perfectly safe to continue using the original instance together with the new instance.

The Copy trait does not change the fact that the compiler will only automatically do bit-wise copies: It is a marker trait with no methods. Its job is only to tell the compiler “it's OK to continue using this after a bit-wise copy”.

The Clone trait isn't that special: It's a regular trait with a method that can do whatever you want it to do. The compiler never uses the Clone trait automatically and doesn't care about what it actually does. However it is clearly intended to create a clone of an instance, so it is perfectly normal to:

  • expect Copy types to implement Clone. After all, Copy is a more strict version of Clone. This is why Copy: Clone and you have to implement Clone on a Copy type.
  • expect Clone on a Copy type to be dumb and only perform a bit-wise copy. You wouldn't want two different semantics here, that would be very confusing. This is why clone is implemented with a simple *self in your example: This dereferences self, which causes a bit-wise copy.

It is however very uncommon to implement those trait manually, and most of the time, you'll just go with derive:

#[derive(Copy, Clone, Debug)]
struct Point {
    x: i32,
    y: i32,
}
like image 165
Matthieu M. Avatar answered Oct 14 '25 07:10

Matthieu M.