Description
This question is tied up in several discussions:
- Semantics of MIR function calls rust#71117
- Semantics of MIR assignments, around aliasing, ordering, and primitives. rust#68364
- What about: use-after-move and (maybe) use-after-drop #188
- MIR: Do we allow accesing a moved place? rust#112564
However it's all somewhat messy and mixed with other questions, making it all a bit hard to follow. Part of the question is where move
operands are even allowed and which places they may work on.
rust-lang/rust#112564 has some nice examples demonstrating that move
is already meaningful today for function calls, and Miri fails to properly model that. I am not aware of similar examples for other uses of move
(in regular MIR assignments). We should at least have a spec explaining today's codegen (and implement it in Miri); I don't know if there are plans for the future here that would require a tighter spec than that.
The function call example lends itself to a semantics like this. At a high level, move
would mean "load the value from the given place, and then deallocate the place it came from, before allocating any of the new memory needed for this statement -- that way the old memory may actually be reused for the new allocation".
However this only makes sense for certain place expressions (move(local.field)
would have to be disallowed). And how does it look like for MIR assignments?
local2 = Aggregate(... move(local) ...)
could mean "load the MiniRust Value
from local
, then dealloc local
like StorageDead, then StorageLive local2
, then store the value in there". But when would that be useful? If local2
was already live before, there's no advantage over just doing
local2 = Aggregate(... copy(local) ...)
StorageDead(local)
so supposedly this should only be used for initializing a value?
Using custom MIR, can we have concrete examples of move
in an assignment causing behavior that Miri cannot currently explain? (Specifically, having memory reused instead of doing a memcpy
.) If no, could we in principle entirely get rid of move
everywhere except for function calls? Cc @bjorn3