Note that "cloning" simply means calling Clone::clone()
, which are entirely a library-defined trait and function. Clone
has nothing to do with any of what you were asking about and what we were discussing.
When a value is moved, then the value is moved. Not any arbitrarily-long buffers pointed to by arbitrary pointers inside the value. That's because this is sufficient for ensuring unique ownership, since the original instance of the value (at the old place) is "invalidated" by the compiler, i.e. you won't be allowed to access it and its destructor – if any – will not be run, so there will be no double-free bugs.
Note that there is nothing special about all of this. It's simple logic. Bits can't literally be "moved" – all of working memory contains some bit pattern at all times, there's no such thing as "physically empty" memory. Thus, "moving" a value from an old place to another will necessarily entail copying the bits; the compiler has to provide the high-level semantics of allowing you or forbidding you from using a particular place, and running or not running a destructor on some values.
This means that when a value doesn't manage any non-trivial resources, then it can be Copy
, i.e., "moving" it by copying its bits to another location doesn't invalidate the old location, since if there isn't a destructor, then there's no possibility for a double-free error. The completely logical and expected consequence of this is that Copy
and Drop
are mutually exclusive. If you have a destructor, you can't just create shallow copies left and right, because that would lead to the destruction of the same resource multiple times.
Duplicating such resources is non-trivial, i.e., it entails more than a bitwise copy, and it requires custom logic. That's what Clone
is for. Types with destructors can't be Copy
but they can be Clone
, which is merely a convention for duplicating instances of a non-trivial type. It isn't and will never be invoked by the compiler implicitly, and the compiler doesn't care about Clone
at all when moving or copying values around.
There is a single relationship between Clone
and Copy
which is completely orthogonal to this discussion and irrelevant to understanding the mechanism of moving, and that is: Copy
has Clone
as a supertrait bound. This, again, is nothing to be surprised of: if something can be duplicated in the very special way of bitwise shallow copying, then it must also be able to be duplicated by user-defined code. Of course, the Clone
impl for a Copy
type usually just forwards to the bitwise copying mechanism (in fact I don't think there's any other valid, non-surprising, best-practice implementation), but the type-level relationship doesn't care about the implementation details. Whatever can be duplicated trivially must also be able to duplicate itself using a method call, it's simple as that.