What happens to `Moved` values?

The vec v1 itself consists of a triple pointer+len+capacity on the stack and data behind that pointer on the heap. A move of v1 to v2 will usually copy the stuff that's on the stack into the new variable, i.e. v2 is a different place on the stack that's also big enough to hold the (pointer, length, capacity) triple and the move will copy this triple from one place to the other.

The "move" part of moving then is achieved by the fact that the compiler knows and remembers that v1 cannot be used anymore after the move (unless it's a mutable variable, then you can move a new vector into it which will overwrite the invalidated triple that points to the same vec that's logically owned by v2). You can think of the data in v1 after the move like garbage data, as if the variable is uninitialized again.

After v1 is moved out of, there will also not be any destructor calls on its old value when it goes out of scope or when it's assigned a new value. In tricky situations where it isn't statically known anymore whether at a particular place in the program v1 has been moved out of, the compiler will insert some extra "drop flag" boolean value on the stack that indicates whether v1 still contains a value that may be accessed and has to be dropped or whether all it contains is "garbage" that must not be accessed through v1 anymore. In such a situation the move itself will also result in this flag being updated.

Finally, and crucially, all this can change after compiler optimizations. The compiler may very well decide to make v1 and v2 actually use the same place on the stack, or even just the same registers without any stack usage, as long as such a change does not affect the program behavior. And in this case the move becomes a no-OP. Avoiding moves like that is in particular common for arguments and return values of a function, in case the function call gets inlined.

So in your code example, since v1 and v2 are never containing a (not moved out) value at the same time, I would be fairly confident that the compiler is turning the two variables into a single one and removing that move operation so that it does nothing at runtime. (In a release build only, where optimizations are turned on.)

9 Likes