I was very pleased with the announcement of Rust 1.21.0 a few days ago. One of the most important language changes listed by the release notes was the automatic promotion of certain constant expressions to
'static lifetime. While reading about this feature, I have encountered the corresponding RFC. The “Extensions” section thereof contains the following assertions:
It would be possible to extend support to
&'static mutreferences, as long as there is the additional constraint that the referenced type is zero sized. […] The zero-sized restriction is there because aliasing mutable references are only safe for zero sized types (since you never dereference the pointer for them).
There are two ways this could be taken further with zero-sized types:
- Remove the
UnsafeCellrestriction if the type of the rvalue is zero-sized.
- The above, but also remove the constexpr restriction, applying to any zero-sized rvalue instead.
Both cases would work because one can’t cause memory unsafety with a reference to a zero sized value, and they would allow more safe code to compile.
It’s not immediately obvious to me how either of these could be true.
First, I’m puzzled by the wording “you never dereference a pointer to zero-sized types”. Who is never dereferencing such pointers? Surely I do if I write
*&(), do I not? Does the RFC author mean that the complier is guaranteed to always turn a deref-of-pointer-to-ZST into a no-op/the singleton value for the ZST/magic? And even if this is the case, how does it guarantee memory safety in the presence of shared mutable pointers?
Second, I feel that “one can’t cause memory unsafety with a reference to a zero sized value” is pretty strong a statement. There is an entire chapter in the Rustonomicon on obscure soundness holes introduced by improper treatment of ZSTs. Could someone also shed some light on what is meant by this one little sentence in this context?