Enum flowistry_pdg::rustc::mir::Operand
source · pub enum Operand<'tcx> {
Copy(Place<'tcx>),
Move(Place<'tcx>),
Constant(Box<Constant<'tcx>, Global>),
}
Expand description
An operand in MIR represents a “value” in Rust, the definition of which is undecided and part of the memory model. One proposal for a definition of values can be found on UCG.
The most common way to create values is via loading a place. Loading a place is an operation which reads the memory of the place and converts it to a value. This is a fundamentally typed operation. The nature of the value produced depends on the type of the conversion. Furthermore, there may be other effects: if the type has a validity constraint loading the place might be UB if the validity constraint is not met.
Needs clarification: Is loading a place that has its variant index set well-formed? Miri currently implements it, but it seems like this may be something to check against in the validator.
Variants§
Copy(Place<'tcx>)
Creates a value by loading the given place.
Before drop elaboration, the type of the place must be Copy
. After drop elaboration there
is no such requirement.
Move(Place<'tcx>)
Creates a value by performing loading the place, just like the Copy
operand.
This may additionally overwrite the place with uninit
bytes, depending on how we decide
in UCG#188. You should not emit MIR that may attempt a subsequent second load of this
place without first re-initializing it.
Needs clarification: The operational impact of Move
is unclear. Currently (both in
Miri and codegen) it has no effect at all unless it appears in an argument to Call
; for
Call
it allows the argument to be passed to the callee “in-place”, i.e. the callee might
just get a reference to this place instead of a full copy. Miri implements this with a
combination of aliasing model “protectors” and putting uninit
into the place. Ralf
proposes that we don’t want these semantics for Move
in regular assignments, because
loading a place should not have side-effects, and the aliasing model “protectors” are
inherently tied to a function call. Are these the semantics we want for MIR? Is this
something we can even decide without knowing more about Rust’s memory model?
Constant(Box<Constant<'tcx>, Global>)
Constants are already semantically values, and remain unchanged.