Discovering self-referential structs 231 Note It can be very hard to detect these issues, and creating simple examples where a move like this causes serious issues is surprisingly difficult. The reason for this is that even though we move everything, the old values are not zeroed or overwritten immediately. Often, they're still there, so dereferencing the preceding pointer would probably produce the correct value. The problem only arises when you change the value of x in the new location, and expect y to point to it. Dereferencing y still produces a valid value in this case, but it's the wrong value. Optimized builds often optimize away needless moves, which can make bugs even harder to detect since most of the program will seem to work just fine, even though it contains a serious bug. What is a move? A move in Rust is one of those concepts that's unfamiliar to many programmers coming from C#, Javascript, and similar garbage-collected languages, and different from what you're used to for C and C++ programmers. The definition of move in Rust is closely related to its ownership system. Moving means transferring ownership. In Rust, a move is the default way of passing values around and it happens every time you change ownership over an object. If the object you move only consists of copy types (types that implement the Copy trait), this is as simple as copying the data over to a new location on the stack. For non-copy types, a move will copy all copy types that it contains over just like in the first example, but now, it will also copy pointers to resources such as heap allocations. The moved-from object is left inaccessible to us (for example, if you try to use the moved-from object, the compilation will fail and let you know that the object has moved), so there is only one owner over the allocation at any point in time. In contrast to cloning, it does not recreate any resources and make a clone of them. One more important thing is that the compiler makes sure that drop is never called on the moved-from object so that the only thing that can free the resources is the new object that took ownership over everything. Figure 9. 2 provides a simplified visual overview of the difference between move, clone, and copy (we've excluded any internal padding of the struct in this visualization). Here, we assume that we have a struct that holds two fields-a copy type, a, which is an i64 type, and a non-copy type, b, which is a Vec<u8> type: