Phantom Data
Sometimes, when working with unsafe code, there may be a situation where lifetimes are associated with a struct, but not part of a field. For example:
struct Iter<'a, T: 'a> {
ptr: *const T,
end: *const T,
}
‘a isn’t being used in the body of this struct, so it’s unbounded. In Rust,
making these types of lifetime annotations for structs is not allowed because
of the implications it would have with maintaining correct variance and drop
checking. The solution Rust offers is PhantomData
, which is a special marker
type. It doesn’t take up more memory, but it simulates a field of the desired struct
type to implement for static analysis. It is easy to implement, the
resulting struct would be:
struct Iter<'a, T: 'a> {
ptr: *const T,
end: *const T,
_marker: marker::PhantomData<&'a T>,
}
This way, the lifetime will be bounded to a “field” of the struct Iter
. This may
bring up complications when writing a tool that automatically generates
bindings to call code because of the way it is designed. As previously
explained, method handles must be written for the different types a
function may be working with, and the FFM API
may be incompatible or unable to accommodate for a case where
PhantomData
is used.
Rust uses unwinding to handle panics (unexpected errors) by default.
In this code, any panic (e.g., an out-of-bounds error) would unwind the stack
safely, cleaning up as it goes. Rust allows opting out of unwinding with
panic=abort
for faster binaries.
To learn more about phantom data, it is recommended to read the official Rust resource The Rustonomicon chapter 3.10.