Consider the following code:
let mut pinned: Pin<&mut T> = ...;
unsafe {
pinned.map_unchecked_mut(|as_mut| {
// Do something to prevent moving the member again.
as_mut.mark_pinned();
&mut as_mut.member
})
}
As the safety requirements clearly lay out:
You must guarantee that the data you return will not move so long as the argument value does not move (for example, because it is one of the fields of that value), and also that you do not move out of the argument you receive to the interior function.
What I'm asking is, how is the compiler stopped from invalidating any assumption I could make to prevent that, locally within the closure that sees merely a &mut _
? Basically the compiler equivalent of this micorarchitectural CPU bug.
Say I behave perfectly fine within mark_pinned
and don't even panic! Within the inner closure we have a &mut _
, so what's stopping the compiler from temporarily reading through the mutable reference to a temporary, call the function on that, and then store the result of the temporary back? Is that a guarantee I can rely upon? I have my doubts, similar strategies seem used in ordinary optimization strategies. If the struct is small enough to be passed inline in a register that even sounds like actual speedup! Basically, since ordinary Rust code must not rely on addresses the usual compilation would allow this, and only spill to a stack temporary when some part is addressed individually as far as I can tell.
Does that analysis have a technical flaw? Is there another reason why the compiler can not do this?