What problem does this solve or what need does it fill?
The PhantomData struct is very useful. It often allows for the creation of safe and abstract API.
But it has two downsides:
- Boilerplate, adding a
_marker: PhantomDatatends to be messy. - Makes the following pattern impossible:
struct Foo<T>; // Where T is "Phantom"
The second is a bit niche, but I have found myself needing it recently
What solution would you like?
A Phantom trait (with special compiler privileges), If a generic type T is specified to implement that, than the compiler
would treat the struct (enum / ..) as though it stores a value of T, even though it doesn't really.
struct Foo<T: Phantom>; // Now possible
Currently, for example:
struct Bytes<'a, T>{
bytes: Box<[u8]>,
_marker: PhantomData<T>,
_lt_marker: PhantomData<&'a ()>
}
// ...
fn as_bytes<'a, T: 'a>(val: T) -> Bytes<'a, T> {
Bytes {
bytes: raw_bytes(val),
_marker: PhantomData,
_lt_marker: PhantomData,
}
}
With Phantom trait:
struct Bytes<'a, T: Phantom + 'a> where &'a (): Phantom {
bytes: Box<[u8]>
}
// ...
fn as_bytes<'a, T: 'a>(val: T) -> Bytes<'a, T> {
Bytes {
bytes: raw_bytes(val)
}
}
Phantom will be an auto trait (or just syntactic sugar in the shape of a trait?)
What alternative(s) have you considered?
Well, as I mentioned, it seems right now there is actually a scenario that's impossible to express.
Other than that, just use the current PhantomData struct.
Additional context
lifetimes are a bit more tricky because you often have to go through the &'a () shenanigans.