Imagine you want to implement your own pointer-like type. In as many respects as possible it should behave exactly like the built in raw pointer types. There are a bunch of possible different reasons to do this, but say for the sake of example you know some data will always be within the first 4GB of address space. That means you can get away with using a 32-bit usize to store your "pointer" instead of a real 64-bit pointer (assuming a platform where
*const T is 64-bit). So you do something like this:
struct SmallPointer<T>(u32, PhantomData<*const T>);
However, this will only work for
T: Sized. For DSTs you need something like:
struct SmallDstPointer<T>(u32, u32, PhantomData<*const T>);
But this isn't ergonomic because generic code that just wants to think about
SmallPointer<T> needs to be conscious of what kind of
T is being dealt with and have redundant paths to deal with the DST case. The built in raw pointers are in effect specialized for DSTs.
Until specialization lands (the tracking issue is 6 years old so I am assuming it's not going to be a short wait) I'm not sure what the best work around is? Maybe with const generics I can do something like:
struct SmallPointer<T>([u32; size_of::<*const T>() / size_of::<*const u8>()], PhantomData<*const T>);
Then I could do runtime checks on the array size being 1 or 2 that should be optimized out by the compiler. But that also seems to require incomplete features (
It also occurs to me maybe I could be taking the pointer type I am trying to emulate as the generic argument instead of the type that is pointed to:
struct SmallPointer<T, P: RawPointerTo<T>>(u32, PhantomData<P>);
Assuming there is a
RawPointerTo trait that is only implemented for raw pointers. But I don't know how to leverage this into determining how many u32s to store.
Is there a best way to do this in stable rust? Failing that what is the best way to do this in nightly rust that has the shortest track to stabilization? I tried googling around for rust and compressed pointers but didn't find any examples to work off of.