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: PhantomData
tends 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.