> For instance `(*role).name` creates a `&mut &'static str` behind the scenes which is illegal, even if we can't observe it because the memory where it points to is not initialized.<p>Where is this coming from? It's literally not true. The MIR for this has:<p><pre><code> ((*_3).0: &str) = const "basic";
((*_3).2: u32) = const 1_u32;
((*_3).1: bool) = const false;
</code></pre>
So it's only going to do a raw offset and then assign to it, which is identical to `*ptr::addr_of_mut!((*role).field) = value`.<p>Sadly there's no way to tell miri to consider `&mut T` valid only if `T` is valid (that choice is not settled yet, AFAIK, at the language design level), in order to demonstrate the difference (<a href="https://github.com/rust-lang/miri/issues/1638" rel="nofollow">https://github.com/rust-lang/miri/issues/1638</a>).<p>The other claim, "dereferencing is illegal", is more likely, but unlike popular misconception, "dereference" is a <i>syntactic</i> concept, that turns a (pointer/reference) "value" into a "place".<p>There's no "operation" of "dereference" to attach <i>dynamic semantics</i> to. After all, `ptr::addr_of_mut!(*p).write(x)` has to remain as valid as `p.write(x)`, and it does literally contain a "dereference" operation (and so do your field projections).<p>So it's still inaccurate. I <i>believe</i> what you want is to say that in `place = value` the destination `place` has to hold a valid value, as if we were doing `mem::replace(&mut place, value)`. This is indeed true for types that have destructors in them, since those would need to run (which in itself is why `write` on pointers exists - it long existed before any of the newer ideas about "indirect validity" in recent years).<p>However, you have `Copy` types there, and those are <i>definitely</i> not different from `<*mut T>::write` to assign to, today. I don't see us having to change that, but I'm also not seeing any references to where these ideas are coming from.<p>> I'm pretty sure we can depend on things being aligned<p>What do you mean "pretty sure"? Of course you can, otherwise it would be UB to allow safe references to those fields! Anything else <i>would be unsound</i>. In fact, this goes hand in hand with the main significant omission of this post: this is <i>not</i> how you're supposed to use `MaybeUninit`.<p>All of this raw pointer stuff is a distraction from the fact that what you want is `&mut MaybeUninit<FieldType>`. Then all of the things about reference validity are <i>necessarily</i> true, and you can <i>safely</i> initialize the value. The only `unsafe` operation in this entire blog post, that isn't unnecessarily added in, is `assume_init`.<p>What the author doesn't mention is that Rust fails to let you convert between `&mut MaybeUninit<Struct>` and some hypothetical `&mut StructBut<replace Field with MaybeUninit<Field>>` because the language isn't powerful enough to do it automatically. This was one of the saddest things about `MaybeUninit` (and we tried to rectify it for at least arrays).<p>This is where I was going to link to a custom derive that someone has written to generate that kind of transform manually (with the necessary check for safe field access wrt alignment). To my shock, I can't find one. Did I see one and did it have a funny name? (the one thing I did find was a macro crate but unlike a derive those have a harder time checking everything so I had to report <a href="https://github.com/youngspe/project-uninit/issues/1" rel="nofollow">https://github.com/youngspe/project-uninit/issues/1</a>)