Differentiate `inner` pointers representing `None` and `Some(ZST)`
For zero-sized-types, rust `Box::into_inner(Box::new(ZST {}))`
returns `1usize as *mut ZST`, which confuses our Java bindings
which check for `None` by checking if `inner < 1024`. While we
could convert the Java bindings to check for `inner == 0`, the
magic value for ZST pointers is not, to my knowledge, an ABI
guarantee Rust provides.
Instead, we add an offset to the `inner` pointers to push them
past the zero page for ZSTs, taking this opportunity to clean up
some of our pointer conversion and push them through a common set
of utility functions.
We also add testing infrastructure to add similar offsets to
non-ZSTs to get good test coverage of the offset addition-removal,
though Rust should largely be ignoring pointer values for ZSTs
anyway so there should be little risk in anything going wrong here.