Is the intention of std::move<unique_ptr> that the "moved-from" pointer no longer has its destructor run?
What if you move a unique_ptr from a std::vector? You don't know which elements of the vector need to have their destructors run.
I think Rust unconditionally doesn't run the destructor of a moved-from Box, but uses drop flags for "maybe-moved-from" local variables, and doesn't allow maybe-moved-from Vec elements.
My point was on handling the moving of trivially copyable types, like int, not those with side effects like unique_ptr. For trivially copyable types, copy and move are (almost) synonymous, and can be made such in Rust with #[derive(Copy)].
But that difference actually gets to your point here. The only difference between copy and move is that a move allows for the new data to overlap the previous. So if you think about what moving from a vector of unique ptr actually means, it must invalidate the vector or remove the element that was moved from the vector. If you want to get the element from the vector without those effects, you have to create a deep copy.
Basically moving without invalidating or mutating such that the moved-from alias can no longer be accessed is necessary.
You’ve referred to two kinds of move there — memmove (overlapping) vs memcpy (non-overlapping memory) and transfers of ownership. In C++ a move appears to always require moving memory with either (depending on aliasing) or via registers. Is that correct?
In Rust, the only thing that has to happen is a transfer of ownership, which does not always mean moving bytes. This greatly simplifies the whole “rvalue reference parameter” thing, because ownership abstracts over wherever you might want to move to. So if your new owner wants it in part of its new stack frame, the compiler is free to just put it there before calling or simply call a destructor on the parent stack frame’s memory in the child. (I don’t know exactly what it likes to do, but it’s all fine.) New owners like Box need to move memory, and that’s cool too, and the compiler is free to reorder the steps to avoid initialising and moving when “placement new” is better. This is also something I believe the compiler is getting better at slowly. The compiler won’t let you safely write moves out of a vector without mutating or taking ownership of the vector, each with moving bytes — otherwise it has access to something it no longer owns.
The easiest example is `let a = A::new(); let b = a;`, which only needs stack space for one A, and for which line 2 is a noop. Its only effect is in when drop is called, if b is in a smaller scope. Does C++ do this too? I would hope so, but it looks like no.
Just copy Rust. Trivially copyable types aren't invalidated by moves, and "move" just aliases copy.